Refactor: Various C++ cleanups to object data transform

Make `XFormObjectData` a real virtual struct instead of using
C style over-allocation. Use C++ arrays and math types.
This commit is contained in:
Hans Goudey
2025-02-16 20:31:09 -05:00
parent a369397301
commit c1c67c918e
16 changed files with 452 additions and 523 deletions

View File

@@ -10,8 +10,11 @@
#include <optional>
#include "BLI_array.hh"
#include "BLI_bounds_types.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_span.hh"
#include "BLI_sys_types.h"
#include "DNA_listBase.h"
@@ -141,19 +144,21 @@ void BKE_curve_nurb_vert_active_set(Curve *cu, const Nurb *nu, const void *vert)
bool BKE_curve_nurb_vert_active_get(Curve *cu, Nurb **r_nu, void **r_vert);
void BKE_curve_nurb_vert_active_validate(Curve *cu);
float (*BKE_curve_nurbs_vert_coords_alloc(const ListBase *lb, int *r_vert_len))[3];
void BKE_curve_nurbs_vert_coords_get(const ListBase *lb, float (*vert_coords)[3], int vert_len);
blender::Array<blender::float3> BKE_curve_nurbs_vert_coords_alloc(const ListBase *lb);
void BKE_curve_nurbs_vert_coords_get(const ListBase *lb,
blender::MutableSpan<blender::float3> vert_coords);
void BKE_curve_nurbs_vert_coords_apply_with_mat4(ListBase *lb,
const float (*vert_coords)[3],
const float mat[4][4],
const blender::Span<blender::float3>,
const blender::float4x4 &transform,
bool constrain_2d);
void BKE_curve_nurbs_vert_coords_apply(ListBase *lb,
const float (*vert_coords)[3],
const blender::Span<blender::float3> vert_coords,
bool constrain_2d);
float (*BKE_curve_nurbs_key_vert_coords_alloc(const ListBase *lb, float *key, int *r_vert_len))[3];
blender::Array<blender::float3> BKE_curve_nurbs_key_vert_coords_alloc(const ListBase *lb,
const float *key);
void BKE_curve_nurbs_key_vert_tilts_apply(ListBase *lb, const float *key);
void BKE_curve_editNurb_keyIndex_delCV(GHash *keyindex, const void *cv);

View File

@@ -1087,13 +1087,6 @@ void BKE_grease_pencil_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
void BKE_grease_pencil_duplicate_drawing_array(const GreasePencil *grease_pencil_src,
GreasePencil *grease_pencil_dst);
struct GreasePencilPointCoordinates {
/* This is used when doing "move only origin" in object_data_transform.cc.
* radius is needs to be stored here as it is tied to object scale. */
float co[3];
float radius;
};
/**
* \note Used for "move only origins" in object_data_transform.cc.
*/
@@ -1102,17 +1095,20 @@ int BKE_grease_pencil_stroke_point_count(const GreasePencil &grease_pencil);
* \note Used for "move only origins" in object_data_transform.cc.
*/
void BKE_grease_pencil_point_coords_get(const GreasePencil &grease_pencil,
GreasePencilPointCoordinates *elem_data);
blender::MutableSpan<blender::float3> all_positions,
blender::MutableSpan<float> all_radii);
/**
* \note Used for "move only origins" in object_data_transform.cc.
*/
void BKE_grease_pencil_point_coords_apply(GreasePencil &grease_pencil,
GreasePencilPointCoordinates *elem_data);
blender::Span<blender::float3> all_positions,
blender::Span<float> all_radii);
/**
* \note Used for "move only origins" in object_data_transform.cc.
*/
void BKE_grease_pencil_point_coords_apply_with_mat4(GreasePencil &grease_pencil,
GreasePencilPointCoordinates *elem_data,
blender::Span<blender::float3> all_positions,
blender::Span<float> all_radii,
const blender::float4x4 &mat);
int BKE_grease_pencil_object_material_index_get_by_name(Object *ob, const char *name);

View File

@@ -7,6 +7,9 @@
#include <string>
#include "BLI_array.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_span.hh"
/** \file
* \ingroup bke
@@ -174,22 +177,27 @@ std::optional<blender::Array<bool>> BKE_keyblock_get_dependent_keys(const Key *k
/**
* \param shape_index: The index to use or all (when -1).
*/
void BKE_keyblock_data_get_from_shape(const Key *key, float (*arr)[3], int shape_index);
void BKE_keyblock_data_get(const Key *key, float (*arr)[3]);
void BKE_keyblock_data_get_from_shape(const Key *key,
blender::MutableSpan<blender::float3> arr,
int shape_index);
void BKE_keyblock_data_get(const Key *key, blender::MutableSpan<blender::float3> arr);
/**
* Set the data to all key-blocks (or shape_index if != -1).
*/
void BKE_keyblock_data_set_with_mat4(Key *key,
int shape_index,
const float (*coords)[3],
const float mat[4][4]);
blender::Span<blender::float3> coords,
const blender::float4x4 &transform);
/**
* Set the data for all key-blocks (or shape_index if != -1),
* transforming by \a mat.
*/
void BKE_keyblock_curve_data_set_with_mat4(
Key *key, const ListBase *nurb, int shape_index, const void *data, const float mat[4][4]);
void BKE_keyblock_curve_data_set_with_mat4(Key *key,
const ListBase *nurb,
int shape_index,
const void *data,
const blender::float4x4 &transform);
/**
* Set the data for all key-blocks (or shape_index if != -1).
*/

View File

@@ -10,9 +10,12 @@
#include <optional>
#include "BLI_array.hh"
#include "BLI_bounds_types.hh"
#include "BLI_compiler_attrs.h"
#include "BLI_math_matrix_types.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_span.hh"
struct BMEditMesh;
struct BPoint;
@@ -31,12 +34,13 @@ void calc_lat_fudu(int flag, int res, float *r_fu, float *r_du);
void outside_lattice(Lattice *lt);
float (*BKE_lattice_vert_coords_alloc(const Lattice *lt, int *r_vert_len))[3];
void BKE_lattice_vert_coords_get(const Lattice *lt, float (*vert_coords)[3]);
blender::Array<blender::float3> BKE_lattice_vert_coords_alloc(const Lattice *lt);
void BKE_lattice_vert_coords_get(const Lattice *lt,
blender::MutableSpan<blender::float3> vert_coordss);
void BKE_lattice_vert_coords_apply_with_mat4(Lattice *lt,
const float (*vert_coords)[3],
const float mat[4][4]);
void BKE_lattice_vert_coords_apply(Lattice *lt, const float (*vert_coords)[3]);
blender::Span<blender::float3> vert_coordss,
const blender::float4x4 &transform);
void BKE_lattice_vert_coords_apply(Lattice *lt, blender::Span<blender::float3> vert_coordss);
void BKE_lattice_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob);
MDeformVert *BKE_lattice_deform_verts_get(const Object *oblatt);

View File

@@ -56,8 +56,12 @@
#include "BLO_read_write.hh"
using blender::Array;
using blender::float3;
using blender::float4x4;
using blender::IndexRange;
using blender::MutableSpan;
using blender::Span;
/* globals */
@@ -4519,69 +4523,63 @@ void BKE_nurb_direction_switch(Nurb *nu)
}
}
void BKE_curve_nurbs_vert_coords_get(const ListBase *lb, float (*vert_coords)[3], int vert_len)
void BKE_curve_nurbs_vert_coords_get(const ListBase *lb, MutableSpan<float3> vert_coords)
{
float *co = vert_coords[0];
int index = 0;
LISTBASE_FOREACH (const Nurb *, nu, lb) {
if (nu->type == CU_BEZIER) {
const BezTriple *bezt = nu->bezt;
for (int i = 0; i < nu->pntsu; i++, bezt++) {
copy_v3_v3(co, bezt->vec[0]);
co += 3;
copy_v3_v3(co, bezt->vec[1]);
co += 3;
copy_v3_v3(co, bezt->vec[2]);
co += 3;
vert_coords[index] = bezt->vec[0];
index++;
vert_coords[index] = bezt->vec[1];
index++;
vert_coords[index] = bezt->vec[2];
index++;
}
}
else {
const BPoint *bp = nu->bp;
for (int i = 0; i < nu->pntsu * nu->pntsv; i++, bp++) {
copy_v3_v3(co, bp->vec);
co += 3;
vert_coords[index] = bp->vec;
index++;
}
}
}
BLI_assert(co == vert_coords[vert_len]);
UNUSED_VARS_NDEBUG(vert_len);
}
float (*BKE_curve_nurbs_vert_coords_alloc(const ListBase *lb, int *r_vert_len))[3]
Array<float3> BKE_curve_nurbs_vert_coords_alloc(const ListBase *lb)
{
const int vert_len = BKE_nurbList_verts_count(lb);
float(*vert_coords)[3] = (float(*)[3])MEM_malloc_arrayN(
vert_len, sizeof(*vert_coords), __func__);
BKE_curve_nurbs_vert_coords_get(lb, vert_coords, vert_len);
*r_vert_len = vert_len;
Array<float3> vert_coords(BKE_nurbList_verts_count(lb));
BKE_curve_nurbs_vert_coords_get(lb, vert_coords);
return vert_coords;
}
void BKE_curve_nurbs_vert_coords_apply_with_mat4(ListBase *lb,
const float (*vert_coords)[3],
const float mat[4][4],
const Span<float3> vert_coords,
const float4x4 &transform,
const bool constrain_2d)
{
const float *co = vert_coords[0];
int index = 0;
LISTBASE_FOREACH (Nurb *, nu, lb) {
if (nu->type == CU_BEZIER) {
BezTriple *bezt = nu->bezt;
for (int i = 0; i < nu->pntsu; i++, bezt++) {
mul_v3_m4v3(bezt->vec[0], mat, co);
co += 3;
mul_v3_m4v3(bezt->vec[1], mat, co);
co += 3;
mul_v3_m4v3(bezt->vec[2], mat, co);
co += 3;
mul_v3_m4v3(bezt->vec[0], transform.ptr(), vert_coords[index]);
index++;
mul_v3_m4v3(bezt->vec[1], transform.ptr(), vert_coords[index]);
index++;
mul_v3_m4v3(bezt->vec[2], transform.ptr(), vert_coords[index]);
index++;
}
}
else {
BPoint *bp = nu->bp;
for (int i = 0; i < nu->pntsu * nu->pntsv; i++, bp++) {
mul_v3_m4v3(bp->vec, mat, co);
co += 3;
mul_v3_m4v3(bp->vec, transform.ptr(), vert_coords[index]);
index++;
}
}
@@ -4594,30 +4592,29 @@ void BKE_curve_nurbs_vert_coords_apply_with_mat4(ListBase *lb,
}
void BKE_curve_nurbs_vert_coords_apply(ListBase *lb,
const float (*vert_coords)[3],
const Span<float3> vert_coords,
const bool constrain_2d)
{
const float *co = vert_coords[0];
int index = 0;
LISTBASE_FOREACH (Nurb *, nu, lb) {
if (nu->type == CU_BEZIER) {
BezTriple *bezt = nu->bezt;
for (int i = 0; i < nu->pntsu; i++, bezt++) {
copy_v3_v3(bezt->vec[0], co);
co += 3;
copy_v3_v3(bezt->vec[1], co);
co += 3;
copy_v3_v3(bezt->vec[2], co);
co += 3;
copy_v3_v3(bezt->vec[0], vert_coords[index]);
index++;
copy_v3_v3(bezt->vec[1], vert_coords[index]);
index++;
copy_v3_v3(bezt->vec[2], vert_coords[index]);
index++;
}
}
else {
BPoint *bp = nu->bp;
for (int i = 0; i < nu->pntsu * nu->pntsv; i++, bp++) {
copy_v3_v3(bp->vec, co);
co += 3;
copy_v3_v3(bp->vec, vert_coords[index]);
index++;
}
}
@@ -4629,23 +4626,22 @@ void BKE_curve_nurbs_vert_coords_apply(ListBase *lb,
}
}
float (*BKE_curve_nurbs_key_vert_coords_alloc(const ListBase *lb, float *key, int *r_vert_len))[3]
Array<float3> BKE_curve_nurbs_key_vert_coords_alloc(const ListBase *lb, const float *key)
{
int vert_len = BKE_nurbList_verts_count(lb);
float(*cos)[3] = (float(*)[3])MEM_malloc_arrayN(vert_len, sizeof(*cos), __func__);
Array<float3> vert_coords(BKE_nurbList_verts_count(lb));
float *co = cos[0];
int index = 0;
LISTBASE_FOREACH (const Nurb *, nu, lb) {
if (nu->type == CU_BEZIER) {
const BezTriple *bezt = nu->bezt;
for (int i = 0; i < nu->pntsu; i++, bezt++) {
copy_v3_v3(co, &key[0]);
co += 3;
copy_v3_v3(co, &key[3]);
co += 3;
copy_v3_v3(co, &key[6]);
co += 3;
vert_coords[index] = &key[0];
index++;
vert_coords[index] = &key[3];
index++;
vert_coords[index] = &key[6];
index++;
key += KEYELEM_FLOAT_LEN_BEZTRIPLE;
}
}
@@ -4653,14 +4649,13 @@ float (*BKE_curve_nurbs_key_vert_coords_alloc(const ListBase *lb, float *key, in
const BPoint *bp = nu->bp;
for (int i = 0; i < nu->pntsu * nu->pntsv; i++, bp++) {
copy_v3_v3(co, key);
co += 3;
vert_coords[index] = key;
index++;
key += KEYELEM_FLOAT_LEN_BPOINT;
}
}
}
*r_vert_len = vert_len;
return cos;
return vert_coords;
}
void BKE_curve_nurbs_key_vert_tilts_apply(ListBase *lb, const float *key)

View File

@@ -41,6 +41,8 @@
#include "DEG_depsgraph.hh"
#include "DEG_depsgraph_query.hh"
using blender::Array;
using blender::float3;
using blender::IndexRange;
static void displist_elem_free(DispList *dl)
@@ -573,8 +575,7 @@ void BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph,
}
float *keyVerts = nullptr;
float(*deformedVerts)[3] = nullptr;
int numVerts = 0;
Array<float3> deformedVerts;
if (!editmode) {
int numElems = 0;
keyVerts = BKE_key_evaluate_object(ob, &numElems);
@@ -586,7 +587,7 @@ void BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph,
* tilts, which is passed through in the modifier stack.
* this is also the reason curves do not use a virtual
* shape key modifier yet. */
deformedVerts = BKE_curve_nurbs_key_vert_coords_alloc(source_nurb, keyVerts, &numVerts);
deformedVerts = BKE_curve_nurbs_key_vert_coords_alloc(source_nurb, keyVerts);
}
}
@@ -609,12 +610,11 @@ void BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph,
blender::bke::ScopedModifierTimer modifier_timer{*md};
if (!deformedVerts) {
deformedVerts = BKE_curve_nurbs_vert_coords_alloc(source_nurb, &numVerts);
if (deformedVerts.is_empty()) {
deformedVerts = BKE_curve_nurbs_vert_coords_alloc(source_nurb);
}
mti->deform_verts(
md, &mectx, nullptr, {reinterpret_cast<blender::float3 *>(deformedVerts), numVerts});
mti->deform_verts(md, &mectx, nullptr, deformedVerts);
if (md == pretessellatePoint) {
break;
@@ -622,9 +622,8 @@ void BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph,
}
}
if (deformedVerts) {
if (!deformedVerts.is_empty()) {
BKE_curve_nurbs_vert_coords_apply(target_nurb, deformedVerts, false);
MEM_freeN(deformedVerts);
}
if (keyVerts) { /* these are not passed through modifier stack */
BKE_curve_nurbs_key_vert_tilts_apply(target_nurb, keyVerts);

View File

@@ -2307,10 +2307,11 @@ int BKE_grease_pencil_stroke_point_count(const GreasePencil &grease_pencil)
}
void BKE_grease_pencil_point_coords_get(const GreasePencil &grease_pencil,
GreasePencilPointCoordinates *elem_data)
blender::MutableSpan<blender::float3> all_positions,
blender::MutableSpan<float> all_radii)
{
using namespace blender;
int64_t index = 0;
for (const int layer_i : grease_pencil.layers().index_range()) {
const bke::greasepencil::Layer &layer = grease_pencil.layer(layer_i);
const float4x4 layer_to_object = layer.local_transform();
@@ -2328,19 +2329,20 @@ void BKE_grease_pencil_point_coords_get(const GreasePencil &grease_pencil,
const VArray<float> radii = drawing.radii();
for (const int i : curves.points_range()) {
copy_v3_v3(elem_data->co, math::transform_point(layer_to_object, positions[i]));
elem_data->radius = radii[i];
elem_data++;
all_positions[index] = math::transform_point(layer_to_object, positions[i]);
all_radii[index] = radii[i];
index++;
}
});
}
}
void BKE_grease_pencil_point_coords_apply(GreasePencil &grease_pencil,
GreasePencilPointCoordinates *elem_data)
blender::Span<blender::float3> all_positions,
blender::Span<float> all_radii)
{
using namespace blender;
int64_t index = 0;
for (const int layer_i : grease_pencil.layers().index_range()) {
bke::greasepencil::Layer &layer = grease_pencil.layer(layer_i);
const float4x4 layer_to_object = layer.local_transform();
@@ -2358,22 +2360,22 @@ void BKE_grease_pencil_point_coords_apply(GreasePencil &grease_pencil,
MutableSpan<float> radii = drawing.radii_for_write();
for (const int i : curves.points_range()) {
positions[i] = math::transform_point(object_to_layer, float3(elem_data->co));
radii[i] = elem_data->radius;
elem_data++;
positions[i] = math::transform_point(object_to_layer, all_positions[index]);
radii[i] = all_radii[index];
index++;
}
});
}
}
void BKE_grease_pencil_point_coords_apply_with_mat4(GreasePencil &grease_pencil,
GreasePencilPointCoordinates *elem_data,
blender::Span<blender::float3> all_positions,
blender::Span<float> all_radii,
const blender::float4x4 &mat)
{
using namespace blender;
const float scalef = mat4_to_scale(mat.ptr());
int64_t index = 0;
for (const int layer_i : grease_pencil.layers().index_range()) {
bke::greasepencil::Layer &layer = grease_pencil.layer(layer_i);
const float4x4 layer_to_object = layer.local_transform();
@@ -2391,9 +2393,9 @@ void BKE_grease_pencil_point_coords_apply_with_mat4(GreasePencil &grease_pencil,
MutableSpan<float> radii = drawing.radii_for_write();
for (const int i : curves.points_range()) {
positions[i] = math::transform_point(object_to_layer * mat, float3(elem_data->co));
radii[i] = elem_data->radius * scalef;
elem_data++;
positions[i] = math::transform_point(object_to_layer * mat, all_positions[index]);
radii[i] = all_radii[index] * scalef;
index++;
}
});
}

View File

@@ -57,6 +57,11 @@
#include "BLO_read_write.hh"
using blender::float3;
using blender::float4x4;
using blender::MutableSpan;
using blender::Span;
static void shapekey_copy_data(Main * /*bmain*/,
std::optional<Library *> /*owner_library*/,
ID *id_dst,
@@ -1677,9 +1682,11 @@ size_t BKE_keyblock_element_calc_size(const Key *key)
* use #BKE_keyblock_element_calc_size to allocate the size of the data needed.
* \{ */
void BKE_keyblock_data_get_from_shape(const Key *key, float (*arr)[3], const int shape_index)
void BKE_keyblock_data_get_from_shape(const Key *key,
MutableSpan<float3> arr,
const int shape_index)
{
uint8_t *elements = (uint8_t *)arr;
uint8_t *elements = (uint8_t *)arr.data();
int index = 0;
for (const KeyBlock *kb = static_cast<const KeyBlock *>(key->block.first); kb;
kb = kb->next, index++)
@@ -1692,22 +1699,22 @@ void BKE_keyblock_data_get_from_shape(const Key *key, float (*arr)[3], const int
}
}
void BKE_keyblock_data_get(const Key *key, float (*arr)[3])
void BKE_keyblock_data_get(const Key *key, MutableSpan<float3> arr)
{
BKE_keyblock_data_get_from_shape(key, arr, -1);
}
void BKE_keyblock_data_set_with_mat4(Key *key,
const int shape_index,
const float (*coords)[3],
const float mat[4][4])
const Span<float3> coords,
const float4x4 &transform)
{
if (key->elemsize != sizeof(float[3])) {
BLI_assert_msg(0, "Invalid elemsize");
return;
}
const float(*elements)[3] = coords;
const float3 *elements = coords.data();
int index = 0;
for (KeyBlock *kb = static_cast<KeyBlock *>(key->block.first); kb; kb = kb->next, index++) {
@@ -1717,15 +1724,18 @@ void BKE_keyblock_data_set_with_mat4(Key *key,
for (int data_offset = 0; data_offset < block_elem_len; ++data_offset) {
const float *src_data = (const float *)(elements + data_offset);
float *dst_data = (float *)(block_data + data_offset);
mul_v3_m4v3(dst_data, mat, src_data);
mul_v3_m4v3(dst_data, transform.ptr(), src_data);
}
elements += block_elem_len;
}
}
}
void BKE_keyblock_curve_data_set_with_mat4(
Key *key, const ListBase *nurb, const int shape_index, const void *data, const float mat[4][4])
void BKE_keyblock_curve_data_set_with_mat4(Key *key,
const ListBase *nurb,
const int shape_index,
const void *data,
const float4x4 &transform)
{
const uint8_t *elements = static_cast<const uint8_t *>(data);
@@ -1733,7 +1743,7 @@ void BKE_keyblock_curve_data_set_with_mat4(
for (KeyBlock *kb = static_cast<KeyBlock *>(key->block.first); kb; kb = kb->next, index++) {
if (ELEM(shape_index, -1, index)) {
const int block_elem_size = kb->totelem * key->elemsize;
BKE_keyblock_curve_data_transform(nurb, mat, elements, kb->data);
BKE_keyblock_curve_data_transform(nurb, transform.ptr(), elements, kb->data);
elements += block_elem_size;
}
}

View File

@@ -43,6 +43,12 @@
#include "BLO_read_write.hh"
using blender::Array;
using blender::float3;
using blender::float4x4;
using blender::MutableSpan;
using blender::Span;
static void lattice_init_data(ID *id)
{
Lattice *lattice = (Lattice *)id;
@@ -477,34 +483,33 @@ void outside_lattice(Lattice *lt)
}
}
void BKE_lattice_vert_coords_get(const Lattice *lt, float (*vert_coords)[3])
void BKE_lattice_vert_coords_get(const Lattice *lt, MutableSpan<float3> vert_coords)
{
const int vert_len = lt->pntsu * lt->pntsv * lt->pntsw;
for (int i = 0; i < vert_len; i++) {
copy_v3_v3(vert_coords[i], lt->def[i].vec);
vert_coords[i] = lt->def[i].vec;
}
}
float (*BKE_lattice_vert_coords_alloc(const Lattice *lt, int *r_vert_len))[3]
Array<float3> BKE_lattice_vert_coords_alloc(const Lattice *lt)
{
const int vert_len = *r_vert_len = lt->pntsu * lt->pntsv * lt->pntsw;
float(*vert_coords)[3] = static_cast<float(*)[3]>(
MEM_mallocN(sizeof(*vert_coords) * vert_len, __func__));
const int vert_len = lt->pntsu * lt->pntsv * lt->pntsw;
Array<float3> vert_coords(vert_len);
BKE_lattice_vert_coords_get(lt, vert_coords);
return vert_coords;
}
void BKE_lattice_vert_coords_apply_with_mat4(Lattice *lt,
const float (*vert_coords)[3],
const float mat[4][4])
const Span<float3> vert_coords,
const float4x4 &transform)
{
int i, numVerts = lt->pntsu * lt->pntsv * lt->pntsw;
for (i = 0; i < numVerts; i++) {
mul_v3_m4v3(lt->def[i].vec, mat, vert_coords[i]);
mul_v3_m4v3(lt->def[i].vec, transform.ptr(), vert_coords[i]);
}
}
void BKE_lattice_vert_coords_apply(Lattice *lt, const float (*vert_coords)[3])
void BKE_lattice_vert_coords_apply(Lattice *lt, const Span<float3> vert_coords)
{
const int vert_len = lt->pntsu * lt->pntsv * lt->pntsw;
for (int i = 0; i < vert_len; i++) {
@@ -523,8 +528,7 @@ void BKE_lattice_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
Lattice *lt = static_cast<Lattice *>(ob->data);
VirtualModifierData virtual_modifier_data;
ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtual_modifier_data);
float(*vert_coords)[3] = nullptr;
int numVerts;
Array<float3> vert_coords;
const bool is_editmode = (lt->editlatt != nullptr);
const ModifierEvalContext mectx = {depsgraph, ob, ModifierApplyFlag(0)};
@@ -547,17 +551,16 @@ void BKE_lattice_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
continue;
}
if (vert_coords == nullptr) {
if (vert_coords.is_empty()) {
/* Get either the edit-mode or regular lattice, whichever is in use now. */
const Lattice *effective_lattice = BKE_object_get_lattice(ob);
vert_coords = BKE_lattice_vert_coords_alloc(effective_lattice, &numVerts);
vert_coords = BKE_lattice_vert_coords_alloc(effective_lattice);
}
mti->deform_verts(
md, &mectx, nullptr, {reinterpret_cast<blender::float3 *>(vert_coords), numVerts});
mti->deform_verts(md, &mectx, nullptr, vert_coords);
}
if (vert_coords == nullptr) {
if (vert_coords.is_empty()) {
return;
}
@@ -568,7 +571,6 @@ void BKE_lattice_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
}
BKE_lattice_vert_coords_apply(lt_eval, vert_coords);
MEM_freeN(vert_coords);
}
MDeformVert *BKE_lattice_deform_verts_get(const Object *oblatt)

View File

@@ -23,7 +23,9 @@
using blender::Array;
using blender::float3;
using blender::float4x4;
using blender::MutableSpan;
using blender::Span;
const BMAllocTemplate bm_mesh_allocsize_default = {512, 1024, 2048, 512};
const BMAllocTemplate bm_mesh_chunksize_default = {512, 1024, 2048, 512};
@@ -1361,7 +1363,7 @@ Array<float3> BM_mesh_vert_coords_alloc(BMesh *bm)
return positions;
}
void BM_mesh_vert_coords_apply(BMesh *bm, const float (*vert_coords)[3])
void BM_mesh_vert_coords_apply(BMesh *bm, const Span<float3> vert_coords)
{
BMIter iter;
BMVert *v;
@@ -1372,14 +1374,14 @@ void BM_mesh_vert_coords_apply(BMesh *bm, const float (*vert_coords)[3])
}
void BM_mesh_vert_coords_apply_with_mat4(BMesh *bm,
const float (*vert_coords)[3],
const float mat[4][4])
const Span<float3> vert_coords,
const float4x4 &transform)
{
BMIter iter;
BMVert *v;
int i;
BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
mul_v3_m4v3(v->co, mat, vert_coords[i]);
mul_v3_m4v3(v->co, transform.ptr(), vert_coords[i]);
}
}

View File

@@ -9,6 +9,7 @@
*/
#include "BLI_array.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_span.hh"
@@ -207,7 +208,7 @@ void BM_mesh_vert_normals_get(BMesh *bm, blender::MutableSpan<blender::float3> n
/* Vertex coords access. */
void BM_mesh_vert_coords_get(BMesh *bm, blender::MutableSpan<blender::float3> positions);
blender::Array<blender::float3> BM_mesh_vert_coords_alloc(BMesh *bm);
void BM_mesh_vert_coords_apply(BMesh *bm, const float (*vert_coords)[3]);
void BM_mesh_vert_coords_apply(BMesh *bm, blender::Span<blender::float3> vert_coords);
void BM_mesh_vert_coords_apply_with_mat4(BMesh *bm,
const float (*vert_coords)[3],
const float mat[4][4]);
blender::Span<blender::float3> vert_coords,
const blender::float4x4 &transform);

View File

@@ -11,6 +11,7 @@
#include <string>
#include "BLI_compiler_attrs.h"
#include "BLI_math_matrix_types.hh"
#include "BLI_string_ref.hh"
#include "BLI_vector.hh"
@@ -561,16 +562,19 @@ bool jump_to_bone(bContext *C, Object *ob, const char *bone_name, bool reveal_hi
/* `object_data_transform.cc` */
XFormObjectData *data_xform_create_ex(ID *id, bool is_edit_mode);
XFormObjectData *data_xform_create(ID *id);
XFormObjectData *data_xform_create_from_edit_mode(ID *id);
struct XFormObjectData {
ID *id;
XFormObjectData() = default;
virtual ~XFormObjectData() = default;
};
void data_xform_destroy(XFormObjectData *xod_base);
std::unique_ptr<XFormObjectData> data_xform_create(ID *id);
std::unique_ptr<XFormObjectData> data_xform_create_from_edit_mode(ID *id);
void data_xform_by_mat4(XFormObjectData *xod, const float mat[4][4]);
void data_xform_by_mat4(XFormObjectData &xod, const float4x4 &transform);
void data_xform_restore(XFormObjectData *xod);
void data_xform_tag_update(XFormObjectData *xod);
void data_xform_restore(XFormObjectData &xod);
void data_xform_tag_update(XFormObjectData &xod);
void ui_template_modifier_asset_menu_items(uiLayout &layout, StringRef catalog_path);

View File

@@ -26,6 +26,7 @@
#include "BLI_math_matrix.h"
#include "BLI_math_rotation.h"
#include "BLI_math_vector.h"
#include "BLI_task.hh"
#include "BKE_armature.hh"
#include "BKE_curve.hh"
@@ -45,8 +46,6 @@
#include "ED_mesh.hh"
#include "ED_object.hh"
#include "MEM_guardedalloc.h"
namespace blender::ed::object {
/* -------------------------------------------------------------------- */
@@ -100,13 +99,14 @@ static ElemData_Armature *armature_coords_and_quats_get_recurse(const ListBase *
return elem;
}
static void armature_coords_and_quats_get(const bArmature *arm, ElemData_Armature *elem_array)
static void armature_coords_and_quats_get(const bArmature *arm,
MutableSpan<ElemData_Armature> elem_array)
{
armature_coords_and_quats_get_recurse(&arm->bonebase, elem_array);
armature_coords_and_quats_get_recurse(&arm->bonebase, elem_array.data());
}
static const ElemData_Armature *armature_coords_and_quats_apply_with_mat4_recurse(
ListBase *bone_base, const ElemData_Armature *elem_array, const float mat[4][4])
ListBase *bone_base, const ElemData_Armature *elem_array, const float4x4 &transform)
{
const ElemData_Armature *elem = elem_array;
LISTBASE_FOREACH (Bone *, bone, bone_base) {
@@ -127,31 +127,32 @@ static const ElemData_Armature *armature_coords_and_quats_apply_with_mat4_recurs
#undef COPY_PTR
#undef COPY_VAL
elem = armature_coords_and_quats_apply_with_mat4_recurse(&bone->childbase, elem + 1, mat);
elem = armature_coords_and_quats_apply_with_mat4_recurse(
&bone->childbase, elem + 1, transform);
}
return elem;
}
static void armature_coords_and_quats_apply_with_mat4(bArmature *arm,
const ElemData_Armature *elem_array,
const float mat[4][4])
const Span<ElemData_Armature> elem_array,
const float4x4 &transform)
{
armature_coords_and_quats_apply_with_mat4_recurse(&arm->bonebase, elem_array, mat);
BKE_armature_transform(arm, mat, true);
armature_coords_and_quats_apply_with_mat4_recurse(&arm->bonebase, elem_array.data(), transform);
BKE_armature_transform(arm, transform.ptr(), true);
}
static void armature_coords_and_quats_apply(bArmature *arm, const ElemData_Armature *elem_array)
static void armature_coords_and_quats_apply(bArmature *arm,
const Span<ElemData_Armature> elem_array)
{
/* Avoid code duplication by using a unit matrix. */
float mat[4][4];
unit_m4(mat);
armature_coords_and_quats_apply_with_mat4(arm, elem_array, mat);
armature_coords_and_quats_apply_with_mat4(arm, elem_array, float4x4::identity());
}
/* Edit Armature */
static void edit_armature_coords_and_quats_get(const bArmature *arm, ElemData_Armature *elem_array)
static void edit_armature_coords_and_quats_get(const bArmature *arm,
MutableSpan<ElemData_Armature> elem_array)
{
ElemData_Armature *elem = elem_array;
ElemData_Armature *elem = elem_array.data();
for (EditBone *ebone = static_cast<EditBone *>(arm->edbo->first); ebone;
ebone = ebone->next, elem++)
{
@@ -172,11 +173,10 @@ static void edit_armature_coords_and_quats_get(const bArmature *arm, ElemData_Ar
}
}
static void edit_armature_coords_and_quats_apply_with_mat4(bArmature *arm,
const ElemData_Armature *elem_array,
const float mat[4][4])
static void edit_armature_coords_and_quats_apply_with_mat4(
bArmature *arm, const Span<ElemData_Armature> elem_array, const float4x4 &transform)
{
const ElemData_Armature *elem = elem_array;
const ElemData_Armature *elem = elem_array.data();
for (EditBone *ebone = static_cast<EditBone *>(arm->edbo->first); ebone;
ebone = ebone->next, elem++)
{
@@ -195,16 +195,14 @@ static void edit_armature_coords_and_quats_apply_with_mat4(bArmature *arm,
#undef COPY_PTR
#undef COPY_VAL
}
ED_armature_edit_transform(arm, mat, true);
ED_armature_edit_transform(arm, transform.ptr(), true);
}
static void edit_armature_coords_and_quats_apply(bArmature *arm,
const ElemData_Armature *elem_array)
const Span<ElemData_Armature> elem_array)
{
/* Avoid code duplication by using a unit matrix. */
float mat[4][4];
unit_m4(mat);
edit_armature_coords_and_quats_apply_with_mat4(arm, elem_array, mat);
edit_armature_coords_and_quats_apply_with_mat4(arm, elem_array, float4x4::identity());
}
/* MetaBall */
@@ -216,9 +214,10 @@ struct ElemData_MetaBall {
float rad;
};
static void metaball_coords_and_quats_get(const MetaBall *mb, ElemData_MetaBall *elem_array)
static void metaball_coords_and_quats_get(const MetaBall *mb,
MutableSpan<ElemData_MetaBall> elem_array)
{
ElemData_MetaBall *elem = elem_array;
ElemData_MetaBall *elem = elem_array.data();
for (const MetaElem *ml = static_cast<const MetaElem *>(mb->elems.first); ml;
ml = ml->next, elem++)
{
@@ -230,25 +229,23 @@ static void metaball_coords_and_quats_get(const MetaBall *mb, ElemData_MetaBall
}
static void metaball_coords_and_quats_apply_with_mat4(MetaBall *mb,
const ElemData_MetaBall *elem_array,
const float mat[4][4])
const Span<ElemData_MetaBall> elem_array,
const float4x4 &transform)
{
const ElemData_MetaBall *elem = elem_array;
const ElemData_MetaBall *elem = elem_array.data();
for (MetaElem *ml = static_cast<MetaElem *>(mb->elems.first); ml; ml = ml->next, elem++) {
copy_v3_v3(&ml->x, elem->co);
copy_qt_qt(ml->quat, elem->quat);
copy_v3_v3(&ml->expx, elem->exp);
ml->rad = elem->rad;
}
BKE_mball_transform(mb, mat, true);
BKE_mball_transform(mb, transform.ptr(), true);
}
static void metaball_coords_and_quats_apply(MetaBall *mb, const ElemData_MetaBall *elem_array)
static void metaball_coords_and_quats_apply(MetaBall *mb, const Span<ElemData_MetaBall> elem_array)
{
/* Avoid code duplication by using a unit matrix. */
float mat[4][4];
unit_m4(mat);
metaball_coords_and_quats_apply_with_mat4(mb, elem_array, mat);
metaball_coords_and_quats_apply_with_mat4(mb, elem_array, float4x4::identity());
}
/** \} */
@@ -261,63 +258,58 @@ static void metaball_coords_and_quats_apply(MetaBall *mb, const ElemData_MetaBal
* Store object data transformation in an opaque struct.
* \{ */
struct XFormObjectData {
ID *id;
bool is_edit_mode;
};
struct XFormObjectData_Mesh {
XFormObjectData base;
struct XFormObjectData_Mesh : public XFormObjectData {
/* Optional data for shape keys. */
void *key_data;
float elem_array[0][3];
Array<float3> key_data;
Array<float3> positions;
bool is_edit_mode = false;
virtual ~XFormObjectData_Mesh() = default;
};
struct XFormObjectData_Lattice {
XFormObjectData base;
struct XFormObjectData_Lattice : public XFormObjectData {
/* Optional data for shape keys. */
void *key_data;
float elem_array[0][3];
Array<float3> key_data;
Array<float3> positions;
bool is_edit_mode = false;
virtual ~XFormObjectData_Lattice() = default;
};
struct XFormObjectData_Curve {
XFormObjectData base;
struct XFormObjectData_Curve : public XFormObjectData {
/* Optional data for shape keys. */
void *key_data;
float elem_array[0][3];
Array<float3> key_data;
Array<float3> positions;
bool is_edit_mode = false;
virtual ~XFormObjectData_Curve() = default;
};
struct XFormObjectData_Armature {
XFormObjectData base;
ElemData_Armature elem_array[0];
struct XFormObjectData_Armature : public XFormObjectData {
Array<ElemData_Armature> elems;
bool is_edit_mode = false;
virtual ~XFormObjectData_Armature() = default;
};
struct XFormObjectData_MetaBall {
XFormObjectData base;
ElemData_MetaBall elem_array[0];
struct XFormObjectData_MetaBall : public XFormObjectData {
Array<ElemData_MetaBall> elems;
bool is_edit_mode = false;
virtual ~XFormObjectData_MetaBall() = default;
};
struct XFormObjectData_GreasePencil {
XFormObjectData base;
GreasePencilPointCoordinates elem_array[0];
struct XFormObjectData_GreasePencil : public XFormObjectData {
Array<float3> positions;
Array<float> radii;
virtual ~XFormObjectData_GreasePencil() = default;
};
struct CurvesPointCoordinates {
/* Radius is needs to be stored here as it is tied to object scale. */
float3 co;
float radius;
struct XFormObjectData_Curves : public XFormObjectData {
Array<float3> positions;
Array<float> radii;
virtual ~XFormObjectData_Curves() = default;
};
struct XFormObjectData_Curves {
XFormObjectData base;
CurvesPointCoordinates elem_array[0];
};
XFormObjectData *data_xform_create_ex(ID *id, bool is_edit_mode)
static std::unique_ptr<XFormObjectData> data_xform_create_ex(ID *id, bool is_edit_mode)
{
XFormObjectData *xod_base = nullptr;
if (id == nullptr) {
return xod_base;
return {};
}
switch (GS(id->name)) {
@@ -330,44 +322,36 @@ XFormObjectData *data_xform_create_ex(ID *id, bool is_edit_mode)
BMesh *bm = mesh->runtime->edit_mesh->bm;
/* Always operate on all keys for the moment. */
// key_index = bm->shapenr - 1;
const int elem_array_len = bm->totvert;
XFormObjectData_Mesh *xod = static_cast<XFormObjectData_Mesh *>(
MEM_mallocN(sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__));
memset(xod, 0x0, sizeof(*xod));
auto xod = std::make_unique<XFormObjectData_Mesh>();
xod->id = id;
xod->is_edit_mode = is_edit_mode;
xod->positions.reinitialize(bm->totvert);
BM_mesh_vert_coords_get(
bm, MutableSpan(reinterpret_cast<float3 *>(xod->elem_array), elem_array_len));
xod_base = &xod->base;
BM_mesh_vert_coords_get(bm, xod->positions.as_mutable_span());
if (key != nullptr) {
const size_t key_size = BKE_keyblock_element_calc_size_from_shape(key, key_index);
if (key_size) {
xod->key_data = MEM_mallocN(key_size, __func__);
BKE_keyblock_data_get_from_shape(
key, static_cast<float(*)[3]>(xod->key_data), key_index);
xod->key_data.reinitialize(key_size);
BKE_keyblock_data_get_from_shape(key, xod->key_data, key_index);
}
}
return xod;
}
else {
const int elem_array_len = mesh->verts_num;
XFormObjectData_Mesh *xod = static_cast<XFormObjectData_Mesh *>(
MEM_mallocN(sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__));
memset(xod, 0x0, sizeof(*xod));
MutableSpan(reinterpret_cast<float3 *>(xod->elem_array), mesh->verts_num)
.copy_from(mesh->vert_positions());
xod_base = &xod->base;
auto xod = std::make_unique<XFormObjectData_Mesh>();
xod->id = id;
xod->is_edit_mode = is_edit_mode;
xod->positions = mesh->vert_positions();
if (key != nullptr) {
const size_t key_size = BKE_keyblock_element_calc_size_from_shape(key, key_index);
if (key_size) {
xod->key_data = MEM_mallocN(key_size, __func__);
BKE_keyblock_data_get_from_shape(
key, static_cast<float(*)[3]>(xod->key_data), key_index);
}
if (key != nullptr) {
const size_t key_size = BKE_keyblock_element_calc_size_from_shape(key, key_index);
if (key_size) {
xod->key_data.reinitialize(key_size);
BKE_keyblock_data_get_from_shape(key, xod->key_data, key_index);
}
}
break;
return xod;
}
case ID_LT: {
Lattice *lt_orig = (Lattice *)id;
@@ -380,24 +364,20 @@ XFormObjectData *data_xform_create_ex(ID *id, bool is_edit_mode)
// key_index = lt_orig->editlatt->shapenr - 1;
}
const int elem_array_len = lt->pntsu * lt->pntsv * lt->pntsw;
XFormObjectData_Lattice *xod = static_cast<XFormObjectData_Lattice *>(
MEM_mallocN(sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__));
memset(xod, 0x0, sizeof(*xod));
BKE_lattice_vert_coords_get(lt, xod->elem_array);
xod_base = &xod->base;
auto xod = std::make_unique<XFormObjectData_Lattice>();
xod->id = id;
xod->is_edit_mode = is_edit_mode;
xod->positions = BKE_lattice_vert_coords_alloc(lt);
if (key != nullptr) {
const size_t key_size = BKE_keyblock_element_calc_size_from_shape(key, key_index);
if (key_size) {
xod->key_data = MEM_mallocN(key_size, __func__);
BKE_keyblock_data_get_from_shape(
key, static_cast<float(*)[3]>(xod->key_data), key_index);
xod->key_data.reinitialize(key_size);
BKE_keyblock_data_get_from_shape(key, xod->key_data, key_index);
}
}
break;
return xod;
}
case ID_CU_LEGACY: {
Curve *cu = (Curve *)id;
@@ -421,269 +401,217 @@ XFormObjectData *data_xform_create_ex(ID *id, bool is_edit_mode)
nurbs = &cu->nurb;
}
const int elem_array_len = BKE_nurbList_verts_count(nurbs);
XFormObjectData_Curve *xod = static_cast<XFormObjectData_Curve *>(
MEM_mallocN(sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__));
memset(xod, 0x0, sizeof(*xod));
BKE_curve_nurbs_vert_coords_get(nurbs, xod->elem_array, elem_array_len);
xod_base = &xod->base;
auto xod = std::make_unique<XFormObjectData_Curve>();
xod->id = id;
xod->is_edit_mode = is_edit_mode;
xod->positions = BKE_curve_nurbs_vert_coords_alloc(nurbs);
if (key != nullptr) {
const size_t key_size = BKE_keyblock_element_calc_size_from_shape(key, key_index);
if (key_size) {
xod->key_data = MEM_mallocN(key_size, __func__);
BKE_keyblock_data_get_from_shape(
key, static_cast<float(*)[3]>(xod->key_data), key_index);
xod->key_data.reinitialize(key_size);
BKE_keyblock_data_get_from_shape(key, xod->key_data, key_index);
}
}
break;
return xod;
}
case ID_AR: {
bArmature *arm = (bArmature *)id;
if (is_edit_mode) {
const int elem_array_len = BLI_listbase_count(arm->edbo);
XFormObjectData_Armature *xod = static_cast<XFormObjectData_Armature *>(
MEM_mallocN(sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__));
memset(xod, 0x0, sizeof(*xod));
edit_armature_coords_and_quats_get(arm, xod->elem_array);
xod_base = &xod->base;
auto xod = std::make_unique<XFormObjectData_Armature>();
xod->id = id;
xod->is_edit_mode = is_edit_mode;
xod->elems.reinitialize(BLI_listbase_count(arm->edbo));
edit_armature_coords_and_quats_get(arm, xod->elems);
return xod;
}
else {
const int elem_array_len = BKE_armature_bonelist_count(&arm->bonebase);
XFormObjectData_Armature *xod = static_cast<XFormObjectData_Armature *>(
MEM_mallocN(sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__));
memset(xod, 0x0, sizeof(*xod));
armature_coords_and_quats_get(arm, xod->elem_array);
xod_base = &xod->base;
}
break;
auto xod = std::make_unique<XFormObjectData_Armature>();
xod->id = id;
xod->is_edit_mode = is_edit_mode;
xod->elems.reinitialize(BKE_armature_bonelist_count(&arm->bonebase));
armature_coords_and_quats_get(arm, xod->elems);
return xod;
}
case ID_MB: {
/* Edit mode and object mode are shared. */
MetaBall *mb = (MetaBall *)id;
const int elem_array_len = BLI_listbase_count(&mb->elems);
XFormObjectData_MetaBall *xod = static_cast<XFormObjectData_MetaBall *>(
MEM_mallocN(sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__));
memset(xod, 0x0, sizeof(*xod));
metaball_coords_and_quats_get(mb, xod->elem_array);
xod_base = &xod->base;
break;
auto xod = std::make_unique<XFormObjectData_MetaBall>();
xod->id = id;
xod->is_edit_mode = is_edit_mode;
xod->elems.reinitialize(BLI_listbase_count(&mb->elems));
metaball_coords_and_quats_get(mb, xod->elems);
return xod;
}
case ID_GP: {
GreasePencil *grease_pencil = (GreasePencil *)id;
const int elem_array_len = BKE_grease_pencil_stroke_point_count(*grease_pencil);
XFormObjectData_GreasePencil *xod = static_cast<XFormObjectData_GreasePencil *>(
MEM_mallocN(sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__));
memset(xod, 0x0, sizeof(*xod));
BKE_grease_pencil_point_coords_get(*grease_pencil, xod->elem_array);
xod_base = &xod->base;
break;
auto xod = std::make_unique<XFormObjectData_GreasePencil>();
xod->id = id;
xod->positions.reinitialize(elem_array_len);
xod->radii.reinitialize(elem_array_len);
BKE_grease_pencil_point_coords_get(*grease_pencil, xod->positions, xod->radii);
return xod;
}
case ID_CV: {
Curves *curves_id = reinterpret_cast<Curves *>(id);
const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
const int elem_array_len = curves.points_num();
XFormObjectData_Curves *xod = static_cast<XFormObjectData_Curves *>(
MEM_mallocN(sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__));
memset(xod, 0x0, sizeof(*xod));
const Span<float3> positions = curves.positions();
const VArraySpan<float> radii = curves.radius();
CurvesPointCoordinates *cpc = xod->elem_array;
for (const int i : curves.points_range()) {
cpc->co = positions[i];
cpc->radius = radii[i];
cpc++;
}
xod_base = &xod->base;
break;
auto xod = std::make_unique<XFormObjectData_GreasePencil>();
xod->id = id;
xod->positions = curves.positions();
xod->radii.reinitialize(curves.points_num());
curves.radius().materialize(xod->radii);
return xod;
}
default: {
break;
return {};
}
}
if (xod_base) {
xod_base->id = id;
xod_base->is_edit_mode = is_edit_mode;
}
return xod_base;
return {};
}
XFormObjectData *data_xform_create(ID *id)
std::unique_ptr<XFormObjectData> data_xform_create(ID *id)
{
return data_xform_create_ex(id, false);
}
XFormObjectData *data_xform_create_from_edit_mode(ID *id)
std::unique_ptr<XFormObjectData> data_xform_create_from_edit_mode(ID *id)
{
return data_xform_create_ex(id, true);
}
void data_xform_destroy(XFormObjectData *xod_base)
static void copy_transformed_positions(const Span<float3> src,
const float4x4 &transform,
MutableSpan<float3> dst)
{
switch (GS(xod_base->id->name)) {
case ID_ME: {
XFormObjectData_Mesh *xod = (XFormObjectData_Mesh *)xod_base;
if (xod->key_data != nullptr) {
MEM_freeN(xod->key_data);
}
break;
threading::parallel_for(src.index_range(), 1024, [&](const IndexRange range) {
for (const int i : range) {
dst[i] = math::transform_point(transform, src[i]);
}
case ID_LT: {
XFormObjectData_Lattice *xod = (XFormObjectData_Lattice *)xod_base;
if (xod->key_data != nullptr) {
MEM_freeN(xod->key_data);
}
break;
}
case ID_CU_LEGACY: {
XFormObjectData_Curve *xod = (XFormObjectData_Curve *)xod_base;
if (xod->key_data != nullptr) {
MEM_freeN(xod->key_data);
}
break;
}
default: {
break;
}
}
MEM_freeN(xod_base);
});
}
void data_xform_by_mat4(XFormObjectData *xod_base, const float mat[4][4])
static void copy_transformed_radii(const Span<float> src,
const float4x4 &transform,
MutableSpan<float> dst)
{
switch (GS(xod_base->id->name)) {
const float scale = mat4_to_scale(transform.ptr());
threading::parallel_for(src.index_range(), 1024, [&](const IndexRange range) {
for (const int i : range) {
dst[i] = src[i] * scale;
}
});
}
void data_xform_by_mat4(XFormObjectData &xod_base, const float4x4 &transform)
{
switch (GS(xod_base.id->name)) {
case ID_ME: {
Mesh *mesh = (Mesh *)xod_base->id;
Mesh *mesh = (Mesh *)xod_base.id;
Key *key = mesh->key;
const int key_index = -1;
XFormObjectData_Mesh *xod = (XFormObjectData_Mesh *)xod_base;
if (xod_base->is_edit_mode) {
const auto &xod = reinterpret_cast<XFormObjectData_Mesh &>(xod_base);
if (xod.is_edit_mode) {
BMesh *bm = mesh->runtime->edit_mesh->bm;
BM_mesh_vert_coords_apply_with_mat4(bm, xod->elem_array, mat);
BM_mesh_vert_coords_apply_with_mat4(bm, xod.positions, transform);
/* Always operate on all keys for the moment. */
// key_index = bm->shapenr - 1;
}
else {
MutableSpan<float3> positions = mesh->vert_positions_for_write();
#ifdef __GNUC__ /* Invalid `xod->elem_array` warning with GCC 13.2.1. */
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Warray-bounds"
#endif
for (const int i : positions.index_range()) {
mul_v3_m4v3(positions[i], mat, xod->elem_array[i]);
}
#ifdef __GNUC__
# pragma GCC diagnostic pop
#endif
copy_transformed_positions(xod.positions, transform, mesh->vert_positions_for_write());
mesh->tag_positions_changed();
}
if (key != nullptr) {
BKE_keyblock_data_set_with_mat4(
key, key_index, static_cast<float(*)[3]>(xod->key_data), mat);
BKE_keyblock_data_set_with_mat4(key, key_index, xod.key_data, transform);
}
break;
}
case ID_LT: {
Lattice *lt_orig = (Lattice *)xod_base->id;
Lattice *lt = xod_base->is_edit_mode ? lt_orig->editlatt->latt : lt_orig;
const auto &xod = reinterpret_cast<XFormObjectData_Lattice &>(xod_base);
Lattice *lt_orig = (Lattice *)xod_base.id;
Lattice *lt = xod.is_edit_mode ? lt_orig->editlatt->latt : lt_orig;
Key *key = lt->key;
const int key_index = -1;
XFormObjectData_Lattice *xod = (XFormObjectData_Lattice *)xod_base;
BKE_lattice_vert_coords_apply_with_mat4(lt, xod->elem_array, mat);
if (xod_base->is_edit_mode) {
BKE_lattice_vert_coords_apply_with_mat4(lt, xod.positions, transform);
if (xod.is_edit_mode) {
/* Always operate on all keys for the moment. */
// key_index = lt_orig->editlatt->shapenr - 1;
}
if ((key != nullptr) && (xod->key_data != nullptr)) {
BKE_keyblock_data_set_with_mat4(
key, key_index, static_cast<float(*)[3]>(xod->key_data), mat);
if ((key != nullptr) && !xod.key_data.is_empty()) {
BKE_keyblock_data_set_with_mat4(key, key_index, xod.key_data, transform);
}
break;
}
case ID_CU_LEGACY: {
BLI_assert(xod_base->is_edit_mode == false); /* Not used currently. */
Curve *cu = (Curve *)xod_base->id;
const auto &xod = reinterpret_cast<XFormObjectData_Curve &>(xod_base);
BLI_assert(xod.is_edit_mode == false); /* Not used currently. */
Curve *cu = (Curve *)xod_base.id;
Key *key = cu->key;
const int key_index = -1;
ListBase *nurb = nullptr;
XFormObjectData_Curve *xod = (XFormObjectData_Curve *)xod_base;
if (xod_base->is_edit_mode) {
if (xod.is_edit_mode) {
EditNurb *editnurb = cu->editnurb;
nurb = &editnurb->nurbs;
BKE_curve_nurbs_vert_coords_apply_with_mat4(
&editnurb->nurbs, xod->elem_array, mat, CU_IS_2D(cu));
&editnurb->nurbs, xod.positions, transform, CU_IS_2D(cu));
/* Always operate on all keys for the moment. */
// key_index = editnurb->shapenr - 1;
}
else {
nurb = &cu->nurb;
BKE_curve_nurbs_vert_coords_apply_with_mat4(&cu->nurb, xod->elem_array, mat, CU_IS_2D(cu));
BKE_curve_nurbs_vert_coords_apply_with_mat4(
&cu->nurb, xod.positions, transform, CU_IS_2D(cu));
}
if ((key != nullptr) && (xod->key_data != nullptr)) {
BKE_keyblock_curve_data_set_with_mat4(key, nurb, key_index, xod->key_data, mat);
if ((key != nullptr) && !xod.key_data.is_empty()) {
BKE_keyblock_curve_data_set_with_mat4(
key, nurb, key_index, xod.key_data.data(), transform);
}
break;
}
case ID_AR: {
BLI_assert(xod_base->is_edit_mode == false); /* Not used currently. */
bArmature *arm = (bArmature *)xod_base->id;
XFormObjectData_Armature *xod = (XFormObjectData_Armature *)xod_base;
if (xod_base->is_edit_mode) {
edit_armature_coords_and_quats_apply_with_mat4(arm, xod->elem_array, mat);
const auto &xod = reinterpret_cast<XFormObjectData_Armature &>(xod_base);
BLI_assert(xod.is_edit_mode == false); /* Not used currently. */
bArmature *arm = (bArmature *)xod_base.id;
if (xod.is_edit_mode) {
edit_armature_coords_and_quats_apply_with_mat4(arm, xod.elems, transform);
}
else {
armature_coords_and_quats_apply_with_mat4(arm, xod->elem_array, mat);
armature_coords_and_quats_apply_with_mat4(arm, xod.elems, transform);
}
break;
}
case ID_MB: {
/* Meta-balls are a special case, edit-mode and object mode data is shared. */
MetaBall *mb = (MetaBall *)xod_base->id;
XFormObjectData_MetaBall *xod = (XFormObjectData_MetaBall *)xod_base;
metaball_coords_and_quats_apply_with_mat4(mb, xod->elem_array, mat);
MetaBall *mb = (MetaBall *)xod_base.id;
const auto &xod = reinterpret_cast<XFormObjectData_MetaBall &>(xod_base);
metaball_coords_and_quats_apply_with_mat4(mb, xod.elems, transform);
break;
}
case ID_GP: {
GreasePencil *grease_pencil = (GreasePencil *)xod_base->id;
XFormObjectData_GreasePencil *xod = (XFormObjectData_GreasePencil *)xod_base;
GreasePencil *grease_pencil = (GreasePencil *)xod_base.id;
const auto &xod = reinterpret_cast<XFormObjectData_GreasePencil &>(xod_base);
BKE_grease_pencil_point_coords_apply_with_mat4(
*grease_pencil, xod->elem_array, float4x4(mat));
*grease_pencil, xod.positions, xod.radii, transform);
break;
}
case ID_CV: {
Curves *curves_id = reinterpret_cast<Curves *>(xod_base->id);
Curves *curves_id = reinterpret_cast<Curves *>(xod_base.id);
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
MutableSpan<float3> positions = curves.positions_for_write();
MutableSpan<float> radii = curves.radius_for_write();
XFormObjectData_Curves *xod = reinterpret_cast<XFormObjectData_Curves *>(xod_base);
CurvesPointCoordinates *cpc = xod->elem_array;
const float scalef = mat4_to_scale(mat);
for (const int i : curves.points_range()) {
positions[i] = math::transform_point(float4x4(mat), cpc->co);
radii[i] = cpc->radius * scalef;
cpc++;
}
const auto &xod = reinterpret_cast<const XFormObjectData_Curves &>(xod_base);
copy_transformed_positions(xod.positions, transform, curves.positions_for_write());
copy_transformed_radii(xod.radii, transform, curves.radius_for_write());
break;
}
default: {
@@ -692,113 +620,106 @@ void data_xform_by_mat4(XFormObjectData *xod_base, const float mat[4][4])
}
}
void data_xform_restore(XFormObjectData *xod_base)
void data_xform_restore(XFormObjectData &xod_base)
{
switch (GS(xod_base->id->name)) {
switch (GS(xod_base.id->name)) {
case ID_ME: {
Mesh *mesh = (Mesh *)xod_base->id;
Mesh *mesh = (Mesh *)xod_base.id;
Key *key = mesh->key;
const int key_index = -1;
XFormObjectData_Mesh *xod = (XFormObjectData_Mesh *)xod_base;
if (xod_base->is_edit_mode) {
const auto &xod = reinterpret_cast<XFormObjectData_Mesh &>(xod_base);
if (xod.is_edit_mode) {
BMesh *bm = mesh->runtime->edit_mesh->bm;
BM_mesh_vert_coords_apply(bm, xod->elem_array);
BM_mesh_vert_coords_apply(bm, xod.positions);
/* Always operate on all keys for the moment. */
// key_index = bm->shapenr - 1;
}
else {
mesh->vert_positions_for_write().copy_from(
{reinterpret_cast<const float3 *>(xod->elem_array), mesh->verts_num});
mesh->vert_positions_for_write().copy_from(xod.positions);
mesh->tag_positions_changed();
}
if ((key != nullptr) && (xod->key_data != nullptr)) {
BKE_keyblock_data_set(key, key_index, xod->key_data);
if ((key != nullptr) && !xod.key_data.is_empty()) {
BKE_keyblock_data_set(key, key_index, xod.key_data.data());
}
break;
}
case ID_LT: {
Lattice *lt_orig = (Lattice *)xod_base->id;
Lattice *lt = xod_base->is_edit_mode ? lt_orig->editlatt->latt : lt_orig;
const auto &xod = reinterpret_cast<XFormObjectData_Lattice &>(xod_base);
Lattice *lt_orig = (Lattice *)xod_base.id;
Lattice *lt = xod.is_edit_mode ? lt_orig->editlatt->latt : lt_orig;
Key *key = lt->key;
const int key_index = -1;
XFormObjectData_Lattice *xod = (XFormObjectData_Lattice *)xod_base;
BKE_lattice_vert_coords_apply(lt, xod->elem_array);
if (xod_base->is_edit_mode) {
BKE_lattice_vert_coords_apply(lt, xod.positions);
if (xod.is_edit_mode) {
/* Always operate on all keys for the moment. */
// key_index = lt_orig->editlatt->shapenr - 1;
}
if ((key != nullptr) && (xod->key_data != nullptr)) {
BKE_keyblock_data_set(key, key_index, xod->key_data);
if ((key != nullptr) && !xod.key_data.is_empty()) {
BKE_keyblock_data_set(key, key_index, xod.key_data.data());
}
break;
}
case ID_CU_LEGACY: {
Curve *cu = (Curve *)xod_base->id;
Curve *cu = (Curve *)xod_base.id;
Key *key = cu->key;
const int key_index = -1;
XFormObjectData_Curve *xod = (XFormObjectData_Curve *)xod_base;
if (xod_base->is_edit_mode) {
const auto &xod = reinterpret_cast<XFormObjectData_Curve &>(xod_base);
if (xod.is_edit_mode) {
EditNurb *editnurb = cu->editnurb;
BKE_curve_nurbs_vert_coords_apply(&editnurb->nurbs, xod->elem_array, CU_IS_2D(cu));
BKE_curve_nurbs_vert_coords_apply(&editnurb->nurbs, xod.positions, CU_IS_2D(cu));
/* Always operate on all keys for the moment. */
// key_index = editnurb->shapenr - 1;
}
else {
BKE_curve_nurbs_vert_coords_apply(&cu->nurb, xod->elem_array, CU_IS_2D(cu));
BKE_curve_nurbs_vert_coords_apply(&cu->nurb, xod.positions, CU_IS_2D(cu));
}
if ((key != nullptr) && (xod->key_data != nullptr)) {
BKE_keyblock_data_set(key, key_index, xod->key_data);
if ((key != nullptr) && !xod.key_data.is_empty()) {
BKE_keyblock_data_set(key, key_index, xod.key_data.data());
}
break;
}
case ID_AR: {
bArmature *arm = (bArmature *)xod_base->id;
XFormObjectData_Armature *xod = (XFormObjectData_Armature *)xod_base;
if (xod_base->is_edit_mode) {
edit_armature_coords_and_quats_apply(arm, xod->elem_array);
bArmature *arm = (bArmature *)xod_base.id;
const auto &xod = reinterpret_cast<XFormObjectData_Armature &>(xod_base);
if (xod.is_edit_mode) {
edit_armature_coords_and_quats_apply(arm, xod.elems);
}
else {
armature_coords_and_quats_apply(arm, xod->elem_array);
armature_coords_and_quats_apply(arm, xod.elems);
}
break;
}
case ID_MB: {
/* Meta-balls are a special case, edit-mode and object mode data is shared. */
MetaBall *mb = (MetaBall *)xod_base->id;
XFormObjectData_MetaBall *xod = (XFormObjectData_MetaBall *)xod_base;
metaball_coords_and_quats_apply(mb, xod->elem_array);
MetaBall *mb = (MetaBall *)xod_base.id;
const auto &xod = reinterpret_cast<XFormObjectData_MetaBall &>(xod_base);
metaball_coords_and_quats_apply(mb, xod.elems);
break;
}
case ID_GP: {
GreasePencil *grease_pencil = (GreasePencil *)xod_base->id;
XFormObjectData_GreasePencil *xod = (XFormObjectData_GreasePencil *)xod_base;
BKE_grease_pencil_point_coords_apply(*grease_pencil, xod->elem_array);
GreasePencil *grease_pencil = (GreasePencil *)xod_base.id;
const auto &xod = reinterpret_cast<XFormObjectData_GreasePencil &>(xod_base);
BKE_grease_pencil_point_coords_apply(*grease_pencil, xod.positions, xod.radii);
break;
}
case ID_CV: {
Curves *curves_id = reinterpret_cast<Curves *>(xod_base->id);
Curves *curves_id = reinterpret_cast<Curves *>(xod_base.id);
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
MutableSpan<float3> positions = curves.positions_for_write();
MutableSpan<float> radii = curves.radius_for_write();
XFormObjectData_Curves *xod = reinterpret_cast<XFormObjectData_Curves *>(xod_base);
CurvesPointCoordinates *cpc = xod->elem_array;
for (const int i : curves.points_range()) {
positions[i] = cpc->co;
radii[i] = cpc->radius;
cpc++;
}
const auto &xod = reinterpret_cast<const XFormObjectData_Curves &>(xod_base);
curves.positions_for_write().copy_from(xod.positions);
curves.radius_for_write().copy_from(xod.radii);
break;
}
default: {
@@ -807,12 +728,13 @@ void data_xform_restore(XFormObjectData *xod_base)
}
}
void data_xform_tag_update(XFormObjectData *xod_base)
void data_xform_tag_update(XFormObjectData &xod_base)
{
switch (GS(xod_base->id->name)) {
switch (GS(xod_base.id->name)) {
case ID_ME: {
Mesh *mesh = (Mesh *)xod_base->id;
if (xod_base->is_edit_mode) {
Mesh *mesh = (Mesh *)xod_base.id;
const auto &xod = reinterpret_cast<XFormObjectData_Mesh &>(xod_base);
if (xod.is_edit_mode) {
EDBMUpdate_Params params{};
params.calc_looptris = true;
params.calc_normals = true;
@@ -824,43 +746,43 @@ void data_xform_tag_update(XFormObjectData *xod_base)
}
case ID_LT: {
/* Generic update. */
Lattice *lt = (Lattice *)xod_base->id;
Lattice *lt = (Lattice *)xod_base.id;
DEG_id_tag_update(&lt->id, ID_RECALC_GEOMETRY);
break;
}
case ID_CU_LEGACY: {
/* Generic update. */
Curve *cu = (Curve *)xod_base->id;
Curve *cu = (Curve *)xod_base.id;
DEG_id_tag_update(&cu->id, ID_RECALC_GEOMETRY);
break;
}
case ID_AR: {
/* Generic update. */
bArmature *arm = (bArmature *)xod_base->id;
bArmature *arm = (bArmature *)xod_base.id;
/* XXX, zero is needed, no other flags properly update this. */
DEG_id_tag_update(&arm->id, 0);
break;
}
case ID_MB: {
/* Generic update. */
MetaBall *mb = (MetaBall *)xod_base->id;
MetaBall *mb = (MetaBall *)xod_base.id;
DEG_id_tag_update(&mb->id, ID_RECALC_GEOMETRY | ID_RECALC_SYNC_TO_EVAL);
break;
}
case ID_GD_LEGACY: {
/* Generic update. */
bGPdata *gpd = (bGPdata *)xod_base->id;
bGPdata *gpd = (bGPdata *)xod_base.id;
DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_SYNC_TO_EVAL);
break;
}
case ID_GP: {
/* Generic update. */
GreasePencil *grease_pencil = (GreasePencil *)xod_base->id;
GreasePencil *grease_pencil = (GreasePencil *)xod_base.id;
DEG_id_tag_update(&grease_pencil->id, ID_RECALC_GEOMETRY | ID_RECALC_SYNC_TO_EVAL);
break;
}
case ID_CV: {
Curves *curves_id = reinterpret_cast<Curves *>(xod_base->id);
Curves *curves_id = reinterpret_cast<Curves *>(xod_base.id);
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
curves.tag_positions_changed();
DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY | ID_RECALC_SYNC_TO_EVAL);

View File

@@ -1400,14 +1400,10 @@ static bool modifier_apply_obdata(ReportList *reports,
RPT_INFO,
"Applied modifier only changed CV points, not tessellated/bevel vertices");
int verts_num;
float(*vertexCos)[3] = BKE_curve_nurbs_vert_coords_alloc(&curve_eval->nurb, &verts_num);
mti->deform_verts(
md_eval, &mectx, nullptr, {reinterpret_cast<float3 *>(vertexCos), verts_num});
Array<float3> vertexCos = BKE_curve_nurbs_vert_coords_alloc(&curve_eval->nurb);
mti->deform_verts(md_eval, &mectx, nullptr, vertexCos);
BKE_curve_nurbs_vert_coords_apply(&curve->nurb, vertexCos, false);
MEM_freeN(vertexCos);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
}
else if (ob->type == OB_LATTICE) {
@@ -1420,13 +1416,9 @@ static bool modifier_apply_obdata(ReportList *reports,
return false;
}
int verts_num;
float(*vertexCos)[3] = BKE_lattice_vert_coords_alloc(lattice, &verts_num);
mti->deform_verts(
md_eval, &mectx, nullptr, {reinterpret_cast<float3 *>(vertexCos), verts_num});
BKE_lattice_vert_coords_apply(lattice, vertexCos);
MEM_freeN(vertexCos);
Array<float3> positions = BKE_lattice_vert_coords_alloc(lattice);
mti->deform_verts(md_eval, &mectx, nullptr, positions);
BKE_lattice_vert_coords_apply(lattice, positions);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
}

View File

@@ -147,23 +147,22 @@ bool calc_active_center(Object *ob, const bool select_only, float r_center[3])
* \{ */
struct XFormObjectSkipChild_Container {
GHash *obchild_in_obmode_map;
GHash *obchild_in_obmode_map = nullptr;
};
struct XFormObjectSkipChild {
float obmat_orig[4][4];
float parent_obmat_orig[4][4];
float parent_obmat_inv_orig[4][4];
float parent_recurse_obmat_orig[4][4];
float parentinv_orig[4][4];
Object *ob_parent_recurse;
int mode;
float obmat_orig[4][4] = {};
float parent_obmat_orig[4][4] = {};
float parent_obmat_inv_orig[4][4] = {};
float parent_recurse_obmat_orig[4][4] = {};
float parentinv_orig[4][4] = {};
Object *ob_parent_recurse = nullptr;
int mode = OB_MODE_OBJECT;
};
XFormObjectSkipChild_Container *xform_skip_child_container_create()
{
XFormObjectSkipChild_Container *xcs = static_cast<XFormObjectSkipChild_Container *>(
MEM_callocN(sizeof(*xcs), __func__));
XFormObjectSkipChild_Container *xcs = MEM_new<XFormObjectSkipChild_Container>(__func__);
if (xcs->obchild_in_obmode_map == nullptr) {
xcs->obchild_in_obmode_map = BLI_ghash_ptr_new(__func__);
}
@@ -229,7 +228,7 @@ void xform_skip_child_container_item_ensure_from_array(XFormObjectSkipChild_Cont
void object_xform_skip_child_container_destroy(XFormObjectSkipChild_Container *xcs)
{
BLI_ghash_free(xcs->obchild_in_obmode_map, nullptr, MEM_freeN);
MEM_freeN(xcs);
MEM_delete(xcs);
}
void object_xform_skip_child_container_item_ensure(XFormObjectSkipChild_Container *xcs,
@@ -239,8 +238,7 @@ void object_xform_skip_child_container_item_ensure(XFormObjectSkipChild_Containe
{
void **xf_p;
if (!BLI_ghash_ensure_p(xcs->obchild_in_obmode_map, ob, &xf_p)) {
XFormObjectSkipChild *xf = static_cast<XFormObjectSkipChild *>(
MEM_mallocN(sizeof(*xf), __func__));
XFormObjectSkipChild *xf = MEM_new<XFormObjectSkipChild>(__func__);
copy_m4_m4(xf->parentinv_orig, ob->parentinv);
copy_m4_m4(xf->obmat_orig, ob->object_to_world().ptr());
copy_m4_m4(xf->parent_obmat_orig, ob->parent->object_to_world().ptr());
@@ -330,13 +328,13 @@ void object_xform_skip_child_container_update_all(XFormObjectSkipChild_Container
* \{ */
struct XFormObjectData_Container {
GHash *obdata_in_obmode_map;
GHash *obdata_in_obmode_map = nullptr;
};
struct XFormObjectData_Extra {
Object *ob;
float obmat_orig[4][4];
XFormObjectData *xod;
Object *ob = nullptr;
float obmat_orig[4][4] = {};
std::unique_ptr<XFormObjectData> xod;
};
void data_xform_container_item_ensure(XFormObjectData_Container *xds, Object *ob)
@@ -347,8 +345,7 @@ void data_xform_container_item_ensure(XFormObjectData_Container *xds, Object *ob
void **xf_p;
if (!BLI_ghash_ensure_p(xds->obdata_in_obmode_map, ob->data, &xf_p)) {
XFormObjectData_Extra *xf = static_cast<XFormObjectData_Extra *>(
MEM_mallocN(sizeof(*xf), __func__));
XFormObjectData_Extra *xf = MEM_new<XFormObjectData_Extra>(__func__);
copy_m4_m4(xf->obmat_orig, ob->object_to_world().ptr());
xf->ob = ob;
/* Result may be nullptr, that's OK. */
@@ -371,17 +368,17 @@ void data_xform_container_update_all(XFormObjectData_Container *xds,
ID *id = static_cast<ID *>(BLI_ghashIterator_getKey(&gh_iter));
XFormObjectData_Extra *xf = static_cast<XFormObjectData_Extra *>(
BLI_ghashIterator_getValue(&gh_iter));
if (xf->xod == nullptr) {
if (!xf->xod) {
continue;
}
Object *ob_eval = DEG_get_evaluated_object(depsgraph, xf->ob);
float imat[4][4], dmat[4][4];
invert_m4_m4(imat, xf->obmat_orig);
mul_m4_m4m4(dmat, imat, ob_eval->object_to_world().ptr());
invert_m4(dmat);
float4x4 imat, dmat;
invert_m4_m4(imat.ptr(), xf->obmat_orig);
mul_m4_m4m4(dmat.ptr(), imat.ptr(), ob_eval->object_to_world().ptr());
invert_m4(dmat.ptr());
data_xform_by_mat4(xf->xod, dmat);
data_xform_by_mat4(*xf->xod, dmat);
if (xf->ob->type == OB_ARMATURE) {
/* TODO: none of the current flags properly update armatures, needs investigation. */
DEG_id_tag_update(id, 0);
@@ -396,16 +393,12 @@ void data_xform_container_update_all(XFormObjectData_Container *xds,
static void trans_obdata_in_obmode_free_elem(void *xf_p)
{
XFormObjectData_Extra *xf = static_cast<XFormObjectData_Extra *>(xf_p);
if (xf->xod) {
data_xform_destroy(xf->xod);
}
MEM_freeN(xf);
MEM_delete(xf);
}
XFormObjectData_Container *data_xform_container_create()
{
XFormObjectData_Container *xds = static_cast<XFormObjectData_Container *>(
MEM_callocN(sizeof(*xds), __func__));
XFormObjectData_Container *xds = MEM_new<XFormObjectData_Container>(__func__);
xds->obdata_in_obmode_map = BLI_ghash_ptr_new(__func__);
return xds;
}
@@ -413,7 +406,7 @@ XFormObjectData_Container *data_xform_container_create()
void data_xform_container_destroy(XFormObjectData_Container *xds)
{
BLI_ghash_free(xds->obdata_in_obmode_map, nullptr, trans_obdata_in_obmode_free_elem);
MEM_freeN(xds);
MEM_delete(xds);
}
/** \} */

View File

@@ -168,7 +168,7 @@ struct ObCustomData_ForEditMode {
ValueInteraction inter;
/** This could be split into a sub-type if we support different kinds of data. */
blender::Array<blender::ed::object::XFormObjectData *> objects_xform;
blender::Array<std::unique_ptr<blender::ed::object::XFormObjectData>> objects_xform;
};
/* Internal callback to free. */
@@ -177,12 +177,6 @@ static void op_generic_value_exit(wmOperator *op)
ObCustomData_ForEditMode *cd = static_cast<ObCustomData_ForEditMode *>(op->customdata);
if (cd) {
interactive_value_exit(&cd->inter);
for (blender::ed::object::XFormObjectData *xod : cd->objects_xform) {
if (xod != nullptr) {
blender::ed::object::data_xform_destroy(xod);
}
}
MEM_delete(cd);
}
@@ -192,9 +186,9 @@ static void op_generic_value_exit(wmOperator *op)
static void op_generic_value_restore(wmOperator *op)
{
ObCustomData_ForEditMode *cd = static_cast<ObCustomData_ForEditMode *>(op->customdata);
for (blender::ed::object::XFormObjectData *xod : cd->objects_xform) {
blender::ed::object::data_xform_restore(xod);
blender::ed::object::data_xform_tag_update(xod);
for (std::unique_ptr<blender::ed::object::XFormObjectData> &xod : cd->objects_xform) {
blender::ed::object::data_xform_restore(*xod);
blender::ed::object::data_xform_tag_update(*xod);
}
}