Refactor: change light linking object storage be dynamically allocated #108090

Closed
Brecht Van Lommel wants to merge 128 commits from light-linking-dna into cycles-light-linking

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
6 changed files with 12 additions and 679 deletions
Showing only changes of commit 1b63a290c6 - Show all commits

View File

@ -25,12 +25,12 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 0
#define BLENDER_FILE_SUBVERSION 1
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file
* was written with too new a version. */
#define BLENDER_FILE_MIN_VERSION 305
#define BLENDER_FILE_MIN_VERSION 306
#define BLENDER_FILE_MIN_SUBVERSION 9
/** User readable version string. */

View File

@ -30,107 +30,51 @@ void BKE_mesh_legacy_convert_uvs_to_struct(
blender::Vector<CustomDataLayer, 16> &loop_layers_to_write);
void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh);
/**
* Move face sets to the legacy type from a generic type.
*/
void BKE_mesh_legacy_face_set_from_generic(
blender::MutableSpan<CustomDataLayer> poly_layers_to_write);
/**
* Copy face sets to the generic data type from the legacy type.
*/
void BKE_mesh_legacy_face_set_to_generic(struct Mesh *mesh);
/**
* Copy edge creases from a separate layer into edges.
*/
void BKE_mesh_legacy_edge_crease_from_layers(struct Mesh *mesh);
/**
* Copy edge creases from edges to a separate layer.
*/
void BKE_mesh_legacy_edge_crease_to_layers(struct Mesh *mesh);
/**
* Copy bevel weights from separate layers into vertices and edges.
*/
void BKE_mesh_legacy_bevel_weight_from_layers(struct Mesh *mesh);
/**
* Copy bevel weights from vertices and edges to separate layers.
*/
void BKE_mesh_legacy_bevel_weight_to_layers(struct Mesh *mesh);
/**
* Convert the hidden element attributes to the old flag format for writing.
*/
void BKE_mesh_legacy_convert_hide_layers_to_flags(struct Mesh *mesh,
blender::MutableSpan<MPoly> legacy_polys);
/**
* Convert the old hide flags (#ME_HIDE) to the hidden element attribute for reading.
* Only add the attributes when there are any elements in each domain hidden.
*/
void BKE_mesh_legacy_convert_flags_to_hide_layers(struct Mesh *mesh);
/**
* Convert the selected element attributes to the old flag format for writing.
*/
void BKE_mesh_legacy_convert_selection_layers_to_flags(struct Mesh *mesh,
blender::MutableSpan<MPoly> legacy_polys);
/**
* Convert the old selection flags (#SELECT/#ME_FACE_SEL) to the selected element attribute for
* reading. Only add the attributes when there are any elements in each domain selected.
*/
void BKE_mesh_legacy_convert_flags_to_selection_layers(struct Mesh *mesh);
/**
* Move material indices from a generic attribute to #MPoly.
*/
void BKE_mesh_legacy_convert_material_indices_to_mpoly(struct Mesh *mesh,
blender::MutableSpan<MPoly> legacy_polys);
/**
* Move material indices from the #MPoly struct to a generic attributes.
* Only add the attribute when the indices are not all zero.
*/
void BKE_mesh_legacy_convert_mpoly_to_material_indices(struct Mesh *mesh);
/** Convert from runtime loose edge cache to legacy edge flag. */
void BKE_mesh_legacy_convert_loose_edges_to_flag(struct Mesh *mesh);
void BKE_mesh_legacy_attribute_flags_to_strings(struct Mesh *mesh);
void BKE_mesh_legacy_attribute_strings_to_flags(struct Mesh *mesh);
void BKE_mesh_legacy_sharp_faces_to_flags(struct Mesh *mesh,
blender::MutableSpan<MPoly> legacy_polys);
void BKE_mesh_legacy_sharp_faces_from_flags(struct Mesh *mesh);
void BKE_mesh_legacy_sharp_edges_to_flags(struct Mesh *mesh);
void BKE_mesh_legacy_sharp_edges_from_flags(struct Mesh *mesh);
void BKE_mesh_legacy_uv_seam_to_flags(struct Mesh *mesh);
void BKE_mesh_legacy_uv_seam_from_flags(struct Mesh *mesh);
struct MVert *BKE_mesh_legacy_convert_positions_to_verts(
Mesh *mesh,
blender::ResourceScope &temp_arrays_for_convert,
blender::Vector<CustomDataLayer, 16> &vert_layers_to_write);
void BKE_mesh_legacy_convert_verts_to_positions(Mesh *mesh);
MEdge *BKE_mesh_legacy_convert_edges_to_medge(
Mesh *mesh,
blender::ResourceScope &temp_arrays_for_convert,
blender::Vector<CustomDataLayer, 16> &edge_layers_to_write);
void BKE_mesh_legacy_convert_edges_to_generic(Mesh *mesh);
struct MLoop *BKE_mesh_legacy_convert_corners_to_loops(
Mesh *mesh,
blender::ResourceScope &temp_arrays_for_convert,
blender::Vector<CustomDataLayer, 16> &loop_layers_to_write);
blender::MutableSpan<MPoly> BKE_mesh_legacy_convert_offsets_to_polys(
const Mesh *mesh,
blender::ResourceScope &temp_arrays_for_convert,
blender::Vector<CustomDataLayer, 16> &poly_layers_to_write);
void BKE_mesh_legacy_convert_polys_to_offsets(Mesh *mesh);
void BKE_mesh_legacy_convert_loops_to_corners(struct Mesh *mesh);

View File

@ -257,68 +257,10 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
mesh->poly_offset_indices = nullptr;
}
else {
Set<std::string> names_to_skip;
if (!BLO_write_is_undo(writer)) {
/* When converting to the old mesh format, don't save redundant attributes. */
names_to_skip.add_multiple_new({"position",
".edge_verts",
".corner_vert",
".corner_edge",
".hide_vert",
".hide_edge",
".hide_poly",
".uv_seam",
".select_vert",
".select_edge",
".select_poly",
"material_index",
"sharp_face",
"sharp_edge"});
mesh->mvert = BKE_mesh_legacy_convert_positions_to_verts(
mesh, temp_arrays_for_legacy_format, vert_layers);
mesh->mloop = BKE_mesh_legacy_convert_corners_to_loops(
mesh, temp_arrays_for_legacy_format, loop_layers);
mesh->medge = BKE_mesh_legacy_convert_edges_to_medge(
mesh, temp_arrays_for_legacy_format, edge_layers);
MutableSpan<MPoly> legacy_polys = BKE_mesh_legacy_convert_offsets_to_polys(
mesh, temp_arrays_for_legacy_format, poly_layers);
BKE_mesh_legacy_convert_hide_layers_to_flags(mesh, legacy_polys);
BKE_mesh_legacy_convert_selection_layers_to_flags(mesh, legacy_polys);
BKE_mesh_legacy_convert_material_indices_to_mpoly(mesh, legacy_polys);
BKE_mesh_legacy_sharp_faces_to_flags(mesh, legacy_polys);
BKE_mesh_legacy_bevel_weight_from_layers(mesh);
BKE_mesh_legacy_edge_crease_from_layers(mesh);
BKE_mesh_legacy_sharp_edges_to_flags(mesh);
BKE_mesh_legacy_uv_seam_to_flags(mesh);
BKE_mesh_legacy_attribute_strings_to_flags(mesh);
mesh->active_color_attribute = nullptr;
mesh->default_color_attribute = nullptr;
BKE_mesh_legacy_convert_loose_edges_to_flag(mesh);
mesh->poly_offset_indices = nullptr;
/* Set deprecated mesh data pointers for forward compatibility. */
mesh->mpoly = legacy_polys.data();
mesh->dvert = const_cast<MDeformVert *>(mesh->deform_verts().data());
}
CustomData_blend_write_prepare(mesh->vdata, vert_layers, names_to_skip);
CustomData_blend_write_prepare(mesh->edata, edge_layers, names_to_skip);
CustomData_blend_write_prepare(mesh->ldata, loop_layers, names_to_skip);
CustomData_blend_write_prepare(mesh->pdata, poly_layers, names_to_skip);
if (!BLO_write_is_undo(writer)) {
/* #CustomData expects the layers to be sorted in increasing order based on type. */
std::stable_sort(
poly_layers.begin(),
poly_layers.end(),
[](const CustomDataLayer &a, const CustomDataLayer &b) { return a.type < b.type; });
BKE_mesh_legacy_convert_uvs_to_struct(mesh, temp_arrays_for_legacy_format, loop_layers);
BKE_mesh_legacy_face_set_from_generic(poly_layers);
}
CustomData_blend_write_prepare(mesh->vdata, vert_layers, {});
CustomData_blend_write_prepare(mesh->edata, edge_layers, {});
CustomData_blend_write_prepare(mesh->ldata, loop_layers, {});
CustomData_blend_write_prepare(mesh->pdata, poly_layers, {});
}
mesh->runtime = nullptr;

View File

@ -1236,25 +1236,6 @@ void BKE_mesh_tessface_ensure(struct Mesh *mesh)
/** \name Sharp Edge Conversion
* \{ */
void BKE_mesh_legacy_sharp_faces_to_flags(Mesh *mesh, blender::MutableSpan<MPoly> legacy_polys)
{
using namespace blender;
if (const bool *sharp_faces = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face")))
{
threading::parallel_for(legacy_polys.index_range(), 4096, [&](const IndexRange range) {
for (const int i : range) {
SET_FLAG_FROM_TEST(legacy_polys[i].flag_legacy, !sharp_faces[i], ME_SMOOTH);
}
});
}
else {
for (const int i : legacy_polys.index_range()) {
legacy_polys[i].flag_legacy |= ME_SMOOTH;
}
}
}
void BKE_mesh_legacy_sharp_faces_from_flags(Mesh *mesh)
{
using namespace blender;
@ -1289,28 +1270,6 @@ void BKE_mesh_legacy_sharp_faces_from_flags(Mesh *mesh)
/** \name Face Set Conversion
* \{ */
void BKE_mesh_legacy_face_set_from_generic(blender::MutableSpan<CustomDataLayer> poly_layers)
{
using namespace blender;
bool changed = false;
for (CustomDataLayer &layer : poly_layers) {
if (StringRef(layer.name) == ".sculpt_face_set") {
layer.type = CD_SCULPT_FACE_SETS;
layer.name[0] = '\0';
changed = true;
break;
}
}
if (!changed) {
return;
}
/* #CustomData expects the layers to be sorted in increasing order based on type. */
std::stable_sort(
poly_layers.begin(),
poly_layers.end(),
[](const CustomDataLayer &a, const CustomDataLayer &b) { return a.type < b.type; });
}
void BKE_mesh_legacy_face_set_to_generic(Mesh *mesh)
{
using namespace blender;
@ -1349,41 +1308,6 @@ void BKE_mesh_legacy_face_set_to_generic(Mesh *mesh)
/** \name Bevel Weight Conversion
* \{ */
void BKE_mesh_legacy_bevel_weight_from_layers(Mesh *mesh)
{
using namespace blender;
MutableSpan<MVert> verts(mesh->mvert, mesh->totvert);
if (const float *weights = static_cast<const float *>(
CustomData_get_layer(&mesh->vdata, CD_BWEIGHT)))
{
mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
for (const int i : verts.index_range()) {
verts[i].bweight_legacy = std::clamp(weights[i], 0.0f, 1.0f) * 255.0f;
}
}
else {
mesh->cd_flag &= ~ME_CDFLAG_VERT_BWEIGHT;
for (const int i : verts.index_range()) {
verts[i].bweight_legacy = 0;
}
}
MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
if (const float *weights = static_cast<const float *>(
CustomData_get_layer(&mesh->edata, CD_BWEIGHT)))
{
mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
for (const int i : edges.index_range()) {
edges[i].bweight_legacy = std::clamp(weights[i], 0.0f, 1.0f) * 255.0f;
}
}
else {
mesh->cd_flag &= ~ME_CDFLAG_EDGE_BWEIGHT;
for (const int i : edges.index_range()) {
edges[i].bweight_legacy = 0;
}
}
}
void BKE_mesh_legacy_bevel_weight_to_layers(Mesh *mesh)
{
using namespace blender;
@ -1416,26 +1340,6 @@ void BKE_mesh_legacy_bevel_weight_to_layers(Mesh *mesh)
/** \name Edge Crease Conversion
* \{ */
void BKE_mesh_legacy_edge_crease_from_layers(Mesh *mesh)
{
using namespace blender;
MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
if (const float *creases = static_cast<const float *>(
CustomData_get_layer(&mesh->edata, CD_CREASE)))
{
mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
for (const int i : edges.index_range()) {
edges[i].crease_legacy = std::clamp(creases[i], 0.0f, 1.0f) * 255.0f;
}
}
else {
mesh->cd_flag &= ~ME_CDFLAG_EDGE_CREASE;
for (const int i : edges.index_range()) {
edges[i].crease_legacy = 0;
}
}
}
void BKE_mesh_legacy_edge_crease_to_layers(Mesh *mesh)
{
using namespace blender;
@ -1458,26 +1362,6 @@ void BKE_mesh_legacy_edge_crease_to_layers(Mesh *mesh)
/** \name Sharp Edge Conversion
* \{ */
void BKE_mesh_legacy_sharp_edges_to_flags(Mesh *mesh)
{
using namespace blender;
MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
if (const bool *sharp_edges = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge")))
{
threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
for (const int i : range) {
SET_FLAG_FROM_TEST(edges[i].flag_legacy, sharp_edges[i], ME_SHARP);
}
});
}
else {
for (const int i : edges.index_range()) {
edges[i].flag_legacy &= ~ME_SHARP;
}
}
}
void BKE_mesh_legacy_sharp_edges_from_flags(Mesh *mesh)
{
using namespace blender;
@ -1511,26 +1395,6 @@ void BKE_mesh_legacy_sharp_edges_from_flags(Mesh *mesh)
/** \name UV Seam Conversion
* \{ */
void BKE_mesh_legacy_uv_seam_to_flags(Mesh *mesh)
{
using namespace blender;
MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
if (const bool *uv_seams = static_cast<const bool *>(
CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, ".uv_seam")))
{
threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
for (const int i : range) {
SET_FLAG_FROM_TEST(edges[i].flag_legacy, uv_seams[i], ME_SEAM);
}
});
}
else {
for (const int i : edges.index_range()) {
edges[i].flag_legacy &= ~ME_SEAM;
}
}
}
void BKE_mesh_legacy_uv_seam_from_flags(Mesh *mesh)
{
using namespace blender;
@ -1564,40 +1428,6 @@ void BKE_mesh_legacy_uv_seam_from_flags(Mesh *mesh)
/** \name Hide Attribute and Legacy Flag Conversion
* \{ */
void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh,
blender::MutableSpan<MPoly> legacy_polys)
{
using namespace blender;
using namespace blender::bke;
const AttributeAccessor attributes = mesh->attributes();
MutableSpan<MVert> verts(mesh->mvert, mesh->totvert);
const VArray<bool> hide_vert = *attributes.lookup_or_default<bool>(
".hide_vert", ATTR_DOMAIN_POINT, false);
threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
SET_FLAG_FROM_TEST(verts[i].flag_legacy, hide_vert[i], ME_HIDE);
}
});
MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
const VArray<bool> hide_edge = *attributes.lookup_or_default<bool>(
".hide_edge", ATTR_DOMAIN_EDGE, false);
threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
SET_FLAG_FROM_TEST(edges[i].flag_legacy, hide_edge[i], ME_HIDE);
}
});
const VArray<bool> hide_poly = *attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
threading::parallel_for(legacy_polys.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
SET_FLAG_FROM_TEST(legacy_polys[i].flag_legacy, hide_poly[i], ME_HIDE);
}
});
}
void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
{
using namespace blender;
@ -1663,21 +1493,6 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
/** \name Material Index Conversion
* \{ */
void BKE_mesh_legacy_convert_material_indices_to_mpoly(Mesh *mesh,
blender::MutableSpan<MPoly> legacy_polys)
{
using namespace blender;
using namespace blender::bke;
const AttributeAccessor attributes = mesh->attributes();
const VArray<int> material_indices = *attributes.lookup_or_default<int>(
"material_index", ATTR_DOMAIN_FACE, 0);
threading::parallel_for(legacy_polys.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
legacy_polys[i].mat_nr_legacy = material_indices[i];
}
});
}
void BKE_mesh_legacy_convert_mpoly_to_material_indices(Mesh *mesh)
{
using namespace blender;
@ -1708,87 +1523,6 @@ void BKE_mesh_legacy_convert_mpoly_to_material_indices(Mesh *mesh)
/** \name Generic UV Map Conversion
* \{ */
static const bool *layers_find_bool_named(const Span<CustomDataLayer> layers,
const blender::StringRef name)
{
for (const CustomDataLayer &layer : layers) {
if (layer.type == CD_PROP_BOOL) {
if (layer.name == name) {
return static_cast<const bool *>(layer.data);
}
}
}
return nullptr;
}
void BKE_mesh_legacy_convert_uvs_to_struct(
Mesh *mesh,
blender::ResourceScope &temp_mloopuv_for_convert,
blender::Vector<CustomDataLayer, 16> &loop_layers_to_write)
{
using namespace blender;
using namespace blender::bke;
const int loops_num = mesh->totloop;
Vector<CustomDataLayer, 16> new_layer_to_write;
/* Don't write the boolean UV map sublayers which will be written in the legacy #MLoopUV type. */
Set<std::string> uv_sublayers_to_skip;
char vert_name[MAX_CUSTOMDATA_LAYER_NAME];
char edge_name[MAX_CUSTOMDATA_LAYER_NAME];
char pin_name[MAX_CUSTOMDATA_LAYER_NAME];
for (const CustomDataLayer &layer : loop_layers_to_write) {
if (layer.type == CD_PROP_FLOAT2) {
uv_sublayers_to_skip.add_multiple_new(
{BKE_uv_map_vert_select_name_get(layer.name, vert_name),
BKE_uv_map_edge_select_name_get(layer.name, edge_name),
BKE_uv_map_pin_name_get(layer.name, pin_name)});
}
}
for (const CustomDataLayer &layer : loop_layers_to_write) {
if (layer.name[0] && uv_sublayers_to_skip.contains_as(layer.name)) {
continue;
}
if (layer.type != CD_PROP_FLOAT2) {
new_layer_to_write.append(layer);
continue;
}
const Span<float2> coords{static_cast<const float2 *>(layer.data), loops_num};
CustomDataLayer mloopuv_layer = layer;
mloopuv_layer.type = CD_MLOOPUV;
MutableSpan<MLoopUV> mloopuv = temp_mloopuv_for_convert.construct<Array<MLoopUV>>(loops_num);
mloopuv_layer.data = mloopuv.data();
char buffer[MAX_CUSTOMDATA_LAYER_NAME];
const bool *vert_selection = layers_find_bool_named(
loop_layers_to_write, BKE_uv_map_vert_select_name_get(layer.name, buffer));
const bool *edge_selection = layers_find_bool_named(
loop_layers_to_write, BKE_uv_map_edge_select_name_get(layer.name, buffer));
const bool *pin = layers_find_bool_named(loop_layers_to_write,
BKE_uv_map_pin_name_get(layer.name, buffer));
threading::parallel_for(mloopuv.index_range(), 2048, [&](IndexRange range) {
for (const int i : range) {
copy_v2_v2(mloopuv[i].uv, coords[i]);
SET_FLAG_FROM_TEST(mloopuv[i].flag, vert_selection && vert_selection[i], MLOOPUV_VERTSEL);
SET_FLAG_FROM_TEST(mloopuv[i].flag, edge_selection && edge_selection[i], MLOOPUV_EDGESEL);
SET_FLAG_FROM_TEST(mloopuv[i].flag, pin && pin[i], MLOOPUV_PINNED);
}
});
new_layer_to_write.append(mloopuv_layer);
}
/* #CustomData expects the layers to be sorted in increasing order based on type. */
std::stable_sort(
new_layer_to_write.begin(),
new_layer_to_write.end(),
[](const CustomDataLayer &a, const CustomDataLayer &b) { return a.type < b.type; });
loop_layers_to_write = new_layer_to_write;
mesh->ldata.totlayer = new_layer_to_write.size();
mesh->ldata.maxlayer = mesh->ldata.totlayer;
}
void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh)
{
using namespace blender;
@ -1918,40 +1652,6 @@ void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh)
/** \name Selection Attribute and Legacy Flag Conversion
* \{ */
void BKE_mesh_legacy_convert_selection_layers_to_flags(Mesh *mesh,
blender::MutableSpan<MPoly> legacy_polys)
{
using namespace blender;
using namespace blender::bke;
const AttributeAccessor attributes = mesh->attributes();
MutableSpan<MVert> verts(mesh->mvert, mesh->totvert);
const VArray<bool> select_vert = *attributes.lookup_or_default<bool>(
".select_vert", ATTR_DOMAIN_POINT, false);
threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
SET_FLAG_FROM_TEST(verts[i].flag_legacy, select_vert[i], SELECT);
}
});
MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
const VArray<bool> select_edge = *attributes.lookup_or_default<bool>(
".select_edge", ATTR_DOMAIN_EDGE, false);
threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
SET_FLAG_FROM_TEST(edges[i].flag_legacy, select_edge[i], SELECT);
}
});
const VArray<bool> select_poly = *attributes.lookup_or_default<bool>(
".select_poly", ATTR_DOMAIN_FACE, false);
threading::parallel_for(legacy_polys.index_range(), 4096, [&](IndexRange range) {
for (const int i : range) {
SET_FLAG_FROM_TEST(legacy_polys[i].flag_legacy, select_poly[i], ME_FACE_SEL);
}
});
}
void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh)
{
using namespace blender;
@ -2013,61 +1713,10 @@ void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Loose Edges
* \{ */
void BKE_mesh_legacy_convert_loose_edges_to_flag(Mesh *mesh)
{
using namespace blender;
using namespace blender::bke;
const LooseEdgeCache &loose_edges = mesh->loose_edges();
MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
if (loose_edges.count == 0) {
for (const int64_t i : range) {
edges[i].flag_legacy &= ~ME_LOOSEEDGE;
}
}
else {
for (const int64_t i : range) {
SET_FLAG_FROM_TEST(edges[i].flag_legacy, loose_edges.is_loose_bits[i], ME_LOOSEEDGE);
}
}
});
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Vertex and Position Conversion
* \{ */
MVert *BKE_mesh_legacy_convert_positions_to_verts(
Mesh *mesh,
blender::ResourceScope &temp_arrays_for_convert,
blender::Vector<CustomDataLayer, 16> &vert_layers_to_write)
{
using namespace blender;
const Span<float3> positions = mesh->vert_positions();
CustomDataLayer mvert_layer{};
mvert_layer.type = CD_MVERT;
MutableSpan<MVert> verts = temp_arrays_for_convert.construct<Array<MVert>>(mesh->totvert);
mvert_layer.data = verts.data();
threading::parallel_for(verts.index_range(), 2048, [&](IndexRange range) {
for (const int i : range) {
copy_v3_v3(verts[i].co_legacy, positions[i]);
}
});
vert_layers_to_write.append(mvert_layer);
return verts.data();
}
void BKE_mesh_legacy_convert_verts_to_positions(Mesh *mesh)
{
using namespace blender;
@ -2098,31 +1747,6 @@ void BKE_mesh_legacy_convert_verts_to_positions(Mesh *mesh)
/** \name MEdge and int2 conversion
* \{ */
MEdge *BKE_mesh_legacy_convert_edges_to_medge(
Mesh *mesh,
blender::ResourceScope &temp_arrays_for_convert,
blender::Vector<CustomDataLayer, 16> &edge_layers_to_write)
{
using namespace blender;
const Span<int2> edges = mesh->edges();
CustomDataLayer medge_layer{};
medge_layer.type = CD_MEDGE;
MutableSpan<MEdge> legacy_edges = temp_arrays_for_convert.construct<Array<MEdge>>(mesh->totedge);
medge_layer.data = legacy_edges.data();
threading::parallel_for(edges.index_range(), 2048, [&](IndexRange range) {
for (const int i : range) {
legacy_edges[i] = {};
legacy_edges[i].v1 = edges[i][0];
legacy_edges[i].v2 = edges[i][1];
}
});
edge_layers_to_write.append(medge_layer);
return legacy_edges.data();
}
void BKE_mesh_legacy_convert_edges_to_generic(Mesh *mesh)
{
using namespace blender;
@ -2217,90 +1841,12 @@ void BKE_mesh_legacy_attribute_flags_to_strings(Mesh *mesh)
default_from_indices(mesh->ldata);
}
void BKE_mesh_legacy_attribute_strings_to_flags(Mesh *mesh)
{
using namespace blender;
CustomData *vdata = &mesh->vdata;
CustomData *ldata = &mesh->ldata;
CustomData_clear_layer_flag(
vdata, CD_PROP_BYTE_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER);
CustomData_clear_layer_flag(
ldata, CD_PROP_BYTE_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER);
CustomData_clear_layer_flag(ldata, CD_PROP_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER);
CustomData_clear_layer_flag(vdata, CD_PROP_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER);
if (const char *name = mesh->active_color_attribute) {
int i;
if ((i = CustomData_get_named_layer_index(vdata, CD_PROP_BYTE_COLOR, name)) != -1) {
CustomData_set_layer_active_index(vdata, CD_PROP_BYTE_COLOR, i);
vdata->layers[i].flag |= CD_FLAG_COLOR_ACTIVE;
}
else if ((i = CustomData_get_named_layer_index(vdata, CD_PROP_COLOR, name)) != -1) {
CustomData_set_layer_active_index(vdata, CD_PROP_COLOR, i);
vdata->layers[i].flag |= CD_FLAG_COLOR_ACTIVE;
}
else if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_BYTE_COLOR, name)) != -1) {
CustomData_set_layer_active_index(ldata, CD_PROP_BYTE_COLOR, i);
ldata->layers[i].flag |= CD_FLAG_COLOR_ACTIVE;
}
else if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_COLOR, name)) != -1) {
CustomData_set_layer_active_index(ldata, CD_PROP_COLOR, i);
ldata->layers[i].flag |= CD_FLAG_COLOR_ACTIVE;
}
}
if (const char *name = mesh->default_color_attribute) {
int i;
if ((i = CustomData_get_named_layer_index(vdata, CD_PROP_BYTE_COLOR, name)) != -1) {
CustomData_set_layer_render_index(vdata, CD_PROP_BYTE_COLOR, i);
vdata->layers[i].flag |= CD_FLAG_COLOR_RENDER;
}
else if ((i = CustomData_get_named_layer_index(vdata, CD_PROP_COLOR, name)) != -1) {
CustomData_set_layer_render_index(vdata, CD_PROP_COLOR, i);
vdata->layers[i].flag |= CD_FLAG_COLOR_RENDER;
}
else if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_BYTE_COLOR, name)) != -1) {
CustomData_set_layer_render_index(ldata, CD_PROP_BYTE_COLOR, i);
ldata->layers[i].flag |= CD_FLAG_COLOR_RENDER;
}
else if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_COLOR, name)) != -1) {
CustomData_set_layer_render_index(ldata, CD_PROP_COLOR, i);
ldata->layers[i].flag |= CD_FLAG_COLOR_RENDER;
}
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Face Corner Conversion
* \{ */
MLoop *BKE_mesh_legacy_convert_corners_to_loops(
Mesh *mesh,
blender::ResourceScope &temp_arrays_for_convert,
blender::Vector<CustomDataLayer, 16> &loop_layers_to_write)
{
using namespace blender;
const Span<int> corner_verts = mesh->corner_verts();
const Span<int> corner_edges = mesh->corner_edges();
CustomDataLayer mloop_layer{};
mloop_layer.type = CD_MLOOP;
MutableSpan<MLoop> loops = temp_arrays_for_convert.construct<Array<MLoop>>(mesh->totloop);
mloop_layer.data = loops.data();
threading::parallel_for(loops.index_range(), 2048, [&](IndexRange range) {
for (const int i : range) {
loops[i].v = corner_verts[i];
loops[i].e = corner_edges[i];
}
});
loop_layers_to_write.append(mloop_layer);
return loops.data();
}
void BKE_mesh_legacy_convert_loops_to_corners(Mesh *mesh)
{
using namespace blender;
@ -2335,30 +1881,6 @@ void BKE_mesh_legacy_convert_loops_to_corners(Mesh *mesh)
/** \name Poly Offset Conversion
* \{ */
blender::MutableSpan<MPoly> BKE_mesh_legacy_convert_offsets_to_polys(
const Mesh *mesh,
blender::ResourceScope &temp_arrays_for_convert,
blender::Vector<CustomDataLayer, 16> &poly_layers_to_write)
{
using namespace blender;
const OffsetIndices polys = mesh->polys();
MutableSpan<MPoly> polys_legacy = temp_arrays_for_convert.construct<Array<MPoly>>(mesh->totpoly);
threading::parallel_for(polys_legacy.index_range(), 2048, [&](IndexRange range) {
for (const int i : range) {
polys_legacy[i].loopstart = polys[i].start();
polys_legacy[i].totloop = polys[i].size();
}
});
CustomDataLayer layer{};
layer.type = CD_MPOLY;
layer.data = polys_legacy.data();
poly_layers_to_write.append(layer);
return polys_legacy;
}
static bool poly_loops_orders_match(const Span<MPoly> polys)
{
for (const int i : polys.index_range().drop_back(1)) {

View File

@ -71,10 +71,6 @@
#include "tracking_private.h"
/* Convert camera object to legacy format where the camera tracks are stored in the MovieTracking
* structure when saving .blend file. */
#define USE_LEGACY_CAMERA_OBJECT_FORMAT_ON_SAVE 1
static void free_buffers(MovieClip *clip);
static void movie_clip_init_data(ID *id)
@ -200,39 +196,6 @@ static void movieclip_blend_write(BlendWriter *writer, ID *id, const void *id_ad
MovieTracking *tracking = &clip->tracking;
#if USE_LEGACY_CAMERA_OBJECT_FORMAT_ON_SAVE
const bool is_undo = BLO_write_is_undo(writer);
/* When using legacy format for camera object assign the list of camera tracks to the
* MovieTracking object. Do it in-place as it simplifies the code a bit, and it is not
* supposed to cause threading issues as no other code is meant to access the legacy fields. */
if (!is_undo) {
MovieTrackingObject *active_tracking_object = BKE_tracking_object_get_active(tracking);
MovieTrackingObject *tracking_camera_object = BKE_tracking_object_get_camera(tracking);
BLI_assert(active_tracking_object != NULL);
BLI_assert(tracking_camera_object != NULL);
tracking->tracks_legacy = tracking_camera_object->tracks;
tracking->plane_tracks_legacy = tracking_camera_object->plane_tracks;
/* The active track in the tracking structure used to be shared across all tracking objects. */
tracking->act_track_legacy = active_tracking_object->active_track;
tracking->act_plane_track_legacy = active_tracking_object->active_plane_track;
tracking->reconstruction_legacy = tracking_camera_object->reconstruction;
}
#endif
/* Assign the pixel-space principal point for forward compatibility. */
/* TODO(sergey): Remove with the next major version update when forward compatibility is allowed
* to be broken. */
if (!is_undo && clip->lastsize[0] != 0 && clip->lastsize[1] != 0) {
tracking_principal_point_normalized_to_pixel(tracking->camera.principal_point,
clip->lastsize[0],
clip->lastsize[1],
tracking->camera.principal_legacy);
}
BLO_write_id_struct(writer, MovieClip, id_address, &clip->id);
BKE_id_blend_write(writer, &clip->id);
@ -241,39 +204,11 @@ static void movieclip_blend_write(BlendWriter *writer, ID *id, const void *id_ad
}
LISTBASE_FOREACH (MovieTrackingObject *, object, &tracking->objects) {
#if USE_LEGACY_CAMERA_OBJECT_FORMAT_ON_SAVE
/* When saving cameras object in the legacy format clear the list of tracks. This is because
* the tracking object code is generic and assumes object owns the tracks in the list. For the
* camera tracks that is not the case in the legacy format. */
if (!is_undo && (object->flag & TRACKING_OBJECT_CAMERA)) {
MovieTrackingObject legacy_object = *object;
BLI_listbase_clear(&legacy_object.tracks);
BLI_listbase_clear(&legacy_object.plane_tracks);
legacy_object.active_track = NULL;
legacy_object.active_plane_track = NULL;
memset(&legacy_object.reconstruction, 0, sizeof(legacy_object.reconstruction));
BLO_write_struct_at_address(writer, MovieTrackingObject, object, &legacy_object);
}
else
#endif
{
BLO_write_struct(writer, MovieTrackingObject, object);
}
BLO_write_struct(writer, MovieTrackingObject, object);
write_movieTracks(writer, &object->tracks);
write_moviePlaneTracks(writer, &object->plane_tracks);
write_movieReconstruction(writer, &object->reconstruction);
}
#if USE_LEGACY_CAMERA_OBJECT_FORMAT_ON_SAVE
if (!is_undo) {
BLI_listbase_clear(&tracking->tracks_legacy);
BLI_listbase_clear(&tracking->plane_tracks_legacy);
tracking->act_track_legacy = NULL;
tracking->act_plane_track_legacy = NULL;
memset(&tracking->reconstruction_legacy, 0, sizeof(tracking->reconstruction_legacy));
}
#endif
}
static void direct_link_movieReconstruction(BlendDataReader *reader,

View File

@ -52,13 +52,6 @@ static void version_motion_tracking_legacy_camera_object(MovieClip &movieclip)
BLI_assert(tracking_camera_object != nullptr);
/* NOTE: The regular .blend file saving converts the new format to the legacy format, but the
* auto-save one does not do this. Likely, the regular saving clears the new storage before
* write, so it can be used to make a decision here.
*
* The idea is basically to not override the new storage if it exists. This is only supposed to
* happen for auto-save files. */
if (BLI_listbase_is_empty(&tracking_camera_object->tracks)) {
tracking_camera_object->tracks = tracking.tracks_legacy;
active_tracking_object->active_track = tracking.act_track_legacy;
@ -92,15 +85,12 @@ static void version_movieclips_legacy_camera_object(Main *bmain)
void blo_do_versions_400(FileData * /*fd*/, Library * /*lib*/, Main *bmain)
{
// if (!MAIN_VERSION_ATLEAST(bmain, 400, 0)) {
/* This is done here because we will continue to write with the old format until 4.0, so we need
* to convert even "current" files. Keep the check commented out for now so the versioning isn't
* turned off right after the 4.0 bump. */
LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
version_mesh_legacy_to_struct_of_array_format(*mesh);
if (!MAIN_VERSION_ATLEAST(bmain, 400, 1)) {
LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
version_mesh_legacy_to_struct_of_array_format(*mesh);
}
version_movieclips_legacy_camera_object(bmain);
}
version_movieclips_legacy_camera_object(bmain);
// }
/**
* Versioning code until next subversion bump goes here.