Cleanup: Use float3, Span, Array for vertex positions
This commit is contained in:
parent
5bdfec8d67
commit
72347f11fe
|
@ -15,6 +15,7 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "BLI_array.hh"
|
#include "BLI_array.hh"
|
||||||
|
#include "BLI_math_vector_types.hh"
|
||||||
|
|
||||||
#include "DNA_customdata_types.h"
|
#include "DNA_customdata_types.h"
|
||||||
|
|
||||||
|
@ -103,14 +104,16 @@ BMEditMesh *BKE_editmesh_from_object(Object *ob);
|
||||||
*/
|
*/
|
||||||
void BKE_editmesh_free_data(BMEditMesh *em);
|
void BKE_editmesh_free_data(BMEditMesh *em);
|
||||||
|
|
||||||
float (*BKE_editmesh_vert_coords_alloc(
|
blender::Array<blender::float3> BKE_editmesh_vert_coords_alloc(Depsgraph *depsgraph,
|
||||||
Depsgraph *depsgraph, BMEditMesh *em, Scene *scene, Object *ob, int *r_vert_len))[3];
|
BMEditMesh *em,
|
||||||
float (*BKE_editmesh_vert_coords_alloc_orco(BMEditMesh *em, int *r_vert_len))[3];
|
Scene *scene,
|
||||||
const float (*BKE_editmesh_vert_coords_when_deformed(Depsgraph *depsgraph,
|
Object *ob);
|
||||||
BMEditMesh *em,
|
blender::Array<blender::float3> BKE_editmesh_vert_coords_alloc_orco(BMEditMesh *em);
|
||||||
Scene *scene,
|
blender::Span<blender::float3> BKE_editmesh_vert_coords_when_deformed(
|
||||||
Object *obedit,
|
Depsgraph *depsgraph,
|
||||||
int *r_vert_len,
|
BMEditMesh *em,
|
||||||
bool *r_is_alloc))[3];
|
Scene *scene,
|
||||||
|
Object *obedit,
|
||||||
|
blender::Array<blender::float3> &r_alloc);
|
||||||
|
|
||||||
void BKE_editmesh_lnorspace_update(BMEditMesh *em);
|
void BKE_editmesh_lnorspace_update(BMEditMesh *em);
|
||||||
|
|
|
@ -26,15 +26,15 @@ int BKE_mesh_wrapper_face_len(const Mesh *mesh);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a contiguous array of vertex position values, if available.
|
* Return a contiguous array of vertex position values, if available.
|
||||||
* Otherwise, vertex positions are stored in BMesh vertices.
|
* Otherwise, vertex positions are stored in BMesh vertices and this returns null.
|
||||||
*/
|
*/
|
||||||
const float (*BKE_mesh_wrapper_vert_coords(const Mesh *mesh))[3];
|
blender::Span<blender::float3> BKE_mesh_wrapper_vert_coords(const Mesh *mesh);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a contiguous array of face normal values, if available.
|
* Return a contiguous array of face normal values, if available.
|
||||||
* Otherwise, normals are stored in BMesh faces.
|
* Otherwise, normals are stored in BMesh faces and this returns null.
|
||||||
*/
|
*/
|
||||||
const float (*BKE_mesh_wrapper_face_normals(Mesh *mesh))[3];
|
blender::Span<blender::float3> BKE_mesh_wrapper_face_normals(Mesh *mesh);
|
||||||
|
|
||||||
void BKE_mesh_wrapper_tag_positions_changed(Mesh *mesh);
|
void BKE_mesh_wrapper_tag_positions_changed(Mesh *mesh);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,10 @@
|
||||||
|
|
||||||
#include "DEG_depsgraph_query.hh"
|
#include "DEG_depsgraph_query.hh"
|
||||||
|
|
||||||
|
using blender::Array;
|
||||||
|
using blender::float3;
|
||||||
|
using blender::Span;
|
||||||
|
|
||||||
BMEditMesh *BKE_editmesh_create(BMesh *bm)
|
BMEditMesh *BKE_editmesh_create(BMesh *bm)
|
||||||
{
|
{
|
||||||
BMEditMesh *em = MEM_new<BMEditMesh>(__func__);
|
BMEditMesh *em = MEM_new<BMEditMesh>(__func__);
|
||||||
|
@ -124,7 +128,7 @@ void BKE_editmesh_free_data(BMEditMesh *em)
|
||||||
|
|
||||||
struct CageUserData {
|
struct CageUserData {
|
||||||
int totvert;
|
int totvert;
|
||||||
float (*cos_cage)[3];
|
blender::MutableSpan<float3> positions_cage;
|
||||||
BLI_bitmap *visit_bitmap;
|
BLI_bitmap *visit_bitmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -137,16 +141,17 @@ static void cage_mapped_verts_callback(void *user_data,
|
||||||
|
|
||||||
if ((index >= 0 && index < data->totvert) && !BLI_BITMAP_TEST(data->visit_bitmap, index)) {
|
if ((index >= 0 && index < data->totvert) && !BLI_BITMAP_TEST(data->visit_bitmap, index)) {
|
||||||
BLI_BITMAP_ENABLE(data->visit_bitmap, index);
|
BLI_BITMAP_ENABLE(data->visit_bitmap, index);
|
||||||
copy_v3_v3(data->cos_cage[index], co);
|
copy_v3_v3(data->positions_cage[index], co);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float (*BKE_editmesh_vert_coords_alloc(
|
Array<float3> BKE_editmesh_vert_coords_alloc(Depsgraph *depsgraph,
|
||||||
Depsgraph *depsgraph, BMEditMesh *em, Scene *scene, Object *ob, int *r_vert_len))[3]
|
BMEditMesh *em,
|
||||||
|
Scene *scene,
|
||||||
|
Object *ob)
|
||||||
{
|
{
|
||||||
Mesh *cage = editbmesh_get_eval_cage(depsgraph, scene, ob, em, &CD_MASK_BAREMESH);
|
Mesh *cage = editbmesh_get_eval_cage(depsgraph, scene, ob, em, &CD_MASK_BAREMESH);
|
||||||
float(*cos_cage)[3] = static_cast<float(*)[3]>(
|
Array<float3> positions_cage(em->bm->totvert);
|
||||||
MEM_callocN(sizeof(*cos_cage) * em->bm->totvert, __func__));
|
|
||||||
|
|
||||||
/* When initializing cage verts, we only want the first cage coordinate for each vertex,
|
/* When initializing cage verts, we only want the first cage coordinate for each vertex,
|
||||||
* so that e.g. mirror or array use original vertex coordinates and not mirrored or duplicate. */
|
* so that e.g. mirror or array use original vertex coordinates and not mirrored or duplicate. */
|
||||||
|
@ -154,38 +159,29 @@ float (*BKE_editmesh_vert_coords_alloc(
|
||||||
|
|
||||||
CageUserData data;
|
CageUserData data;
|
||||||
data.totvert = em->bm->totvert;
|
data.totvert = em->bm->totvert;
|
||||||
data.cos_cage = cos_cage;
|
data.positions_cage = positions_cage;
|
||||||
data.visit_bitmap = visit_bitmap;
|
data.visit_bitmap = visit_bitmap;
|
||||||
|
|
||||||
BKE_mesh_foreach_mapped_vert(cage, cage_mapped_verts_callback, &data, MESH_FOREACH_NOP);
|
BKE_mesh_foreach_mapped_vert(cage, cage_mapped_verts_callback, &data, MESH_FOREACH_NOP);
|
||||||
|
|
||||||
MEM_freeN(visit_bitmap);
|
MEM_freeN(visit_bitmap);
|
||||||
|
|
||||||
if (r_vert_len) {
|
return positions_cage;
|
||||||
*r_vert_len = em->bm->totvert;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cos_cage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const float (*BKE_editmesh_vert_coords_when_deformed(Depsgraph *depsgraph,
|
Span<float3> BKE_editmesh_vert_coords_when_deformed(
|
||||||
BMEditMesh *em,
|
Depsgraph *depsgraph, BMEditMesh *em, Scene *scene, Object *ob, Array<float3> &r_alloc)
|
||||||
Scene *scene,
|
|
||||||
Object *ob,
|
|
||||||
int *r_vert_len,
|
|
||||||
bool *r_is_alloc))[3]
|
|
||||||
{
|
{
|
||||||
const float(*coords)[3] = nullptr;
|
|
||||||
*r_is_alloc = false;
|
|
||||||
|
|
||||||
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
|
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
|
||||||
Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object_eval);
|
Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object_eval);
|
||||||
Mesh *mesh_cage = BKE_object_get_editmesh_eval_cage(ob);
|
Mesh *mesh_cage = BKE_object_get_editmesh_eval_cage(ob);
|
||||||
|
|
||||||
|
Span<float3> vert_positions;
|
||||||
if (mesh_cage && mesh_cage->runtime->deformed_only) {
|
if (mesh_cage && mesh_cage->runtime->deformed_only) {
|
||||||
BLI_assert(BKE_mesh_wrapper_vert_len(mesh_cage) == em->bm->totvert);
|
BLI_assert(BKE_mesh_wrapper_vert_len(mesh_cage) == em->bm->totvert);
|
||||||
/* Deformed, and we have deformed coords already. */
|
/* Deformed, and we have deformed coords already. */
|
||||||
coords = BKE_mesh_wrapper_vert_coords(mesh_cage);
|
vert_positions = BKE_mesh_wrapper_vert_coords(mesh_cage);
|
||||||
}
|
}
|
||||||
else if ((editmesh_eval_final != nullptr) &&
|
else if ((editmesh_eval_final != nullptr) &&
|
||||||
(editmesh_eval_final->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH))
|
(editmesh_eval_final->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH))
|
||||||
|
@ -194,15 +190,15 @@ const float (*BKE_editmesh_vert_coords_when_deformed(Depsgraph *depsgraph,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Constructive modifiers have been used, we need to allocate coordinates. */
|
/* Constructive modifiers have been used, we need to allocate coordinates. */
|
||||||
*r_is_alloc = true;
|
r_alloc = BKE_editmesh_vert_coords_alloc(depsgraph, em, scene, ob);
|
||||||
coords = BKE_editmesh_vert_coords_alloc(depsgraph, em, scene, ob, r_vert_len);
|
return r_alloc.as_span();
|
||||||
}
|
}
|
||||||
return coords;
|
return vert_positions;
|
||||||
}
|
}
|
||||||
|
|
||||||
float (*BKE_editmesh_vert_coords_alloc_orco(BMEditMesh *em, int *r_vert_len))[3]
|
Array<float3> BKE_editmesh_vert_coords_alloc_orco(BMEditMesh *em)
|
||||||
{
|
{
|
||||||
return BM_mesh_vert_coords_alloc(em->bm, r_vert_len);
|
return BM_mesh_vert_coords_alloc(em->bm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BKE_editmesh_lnorspace_update(BMEditMesh *em)
|
void BKE_editmesh_lnorspace_update(BMEditMesh *em)
|
||||||
|
|
|
@ -81,8 +81,7 @@ void BKE_editmesh_cache_ensure_face_centers(BMEditMesh &em, blender::bke::EditMe
|
||||||
else {
|
else {
|
||||||
BM_mesh_elem_index_ensure(bm, BM_VERT);
|
BM_mesh_elem_index_ensure(bm, BM_VERT);
|
||||||
BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
|
BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
|
||||||
BM_face_calc_center_median_vcos(
|
BM_face_calc_center_median_vcos(bm, efa, emd.faceCos[i], emd.vertexCos);
|
||||||
bm, efa, emd.faceCos[i], reinterpret_cast<const float(*)[3]>(emd.vertexCos.data()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,35 +148,31 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *mesh)
|
||||||
/** \name Mesh Coordinate Access
|
/** \name Mesh Coordinate Access
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
const float (*BKE_mesh_wrapper_vert_coords(const Mesh *mesh))[3]
|
Span<float3> BKE_mesh_wrapper_vert_coords(const Mesh *mesh)
|
||||||
{
|
{
|
||||||
switch (mesh->runtime->wrapper_type) {
|
switch (mesh->runtime->wrapper_type) {
|
||||||
case ME_WRAPPER_TYPE_BMESH:
|
case ME_WRAPPER_TYPE_BMESH:
|
||||||
if (mesh->runtime->edit_data->vertexCos.is_empty()) {
|
return mesh->runtime->edit_data->vertexCos;
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return reinterpret_cast<const float(*)[3]>(mesh->runtime->edit_data->vertexCos.data());
|
|
||||||
case ME_WRAPPER_TYPE_MDATA:
|
case ME_WRAPPER_TYPE_MDATA:
|
||||||
case ME_WRAPPER_TYPE_SUBD:
|
case ME_WRAPPER_TYPE_SUBD:
|
||||||
return reinterpret_cast<const float(*)[3]>(mesh->vert_positions().data());
|
return mesh->vert_positions();
|
||||||
}
|
}
|
||||||
return nullptr;
|
BLI_assert_unreachable();
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const float (*BKE_mesh_wrapper_face_normals(Mesh *mesh))[3]
|
Span<float3> BKE_mesh_wrapper_face_normals(Mesh *mesh)
|
||||||
{
|
{
|
||||||
switch (mesh->runtime->wrapper_type) {
|
switch (mesh->runtime->wrapper_type) {
|
||||||
case ME_WRAPPER_TYPE_BMESH:
|
case ME_WRAPPER_TYPE_BMESH:
|
||||||
BKE_editmesh_cache_ensure_face_normals(*mesh->runtime->edit_mesh, *mesh->runtime->edit_data);
|
BKE_editmesh_cache_ensure_face_normals(*mesh->runtime->edit_mesh, *mesh->runtime->edit_data);
|
||||||
if (mesh->runtime->edit_data->faceNos.is_empty()) {
|
return mesh->runtime->edit_data->faceNos;
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return reinterpret_cast<const float(*)[3]>(mesh->runtime->edit_data->faceNos.data());
|
|
||||||
case ME_WRAPPER_TYPE_MDATA:
|
case ME_WRAPPER_TYPE_MDATA:
|
||||||
case ME_WRAPPER_TYPE_SUBD:
|
case ME_WRAPPER_TYPE_SUBD:
|
||||||
return reinterpret_cast<const float(*)[3]>(mesh->face_normals().data());
|
return mesh->face_normals();
|
||||||
}
|
}
|
||||||
return nullptr;
|
BLI_assert_unreachable();
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void BKE_mesh_wrapper_tag_positions_changed(Mesh *mesh)
|
void BKE_mesh_wrapper_tag_positions_changed(Mesh *mesh)
|
||||||
|
|
|
@ -22,6 +22,10 @@
|
||||||
|
|
||||||
#include "bmesh.hh"
|
#include "bmesh.hh"
|
||||||
|
|
||||||
|
using blender::Array;
|
||||||
|
using blender::float3;
|
||||||
|
using blender::MutableSpan;
|
||||||
|
|
||||||
const BMAllocTemplate bm_mesh_allocsize_default = {512, 1024, 2048, 512};
|
const BMAllocTemplate bm_mesh_allocsize_default = {512, 1024, 2048, 512};
|
||||||
const BMAllocTemplate bm_mesh_chunksize_default = {512, 1024, 2048, 512};
|
const BMAllocTemplate bm_mesh_chunksize_default = {512, 1024, 2048, 512};
|
||||||
|
|
||||||
|
@ -1328,23 +1332,21 @@ void BM_mesh_toolflags_set(BMesh *bm, bool use_toolflags)
|
||||||
/** \name BMesh Coordinate Access
|
/** \name BMesh Coordinate Access
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
void BM_mesh_vert_coords_get(BMesh *bm, float (*vert_coords)[3])
|
void BM_mesh_vert_coords_get(BMesh *bm, MutableSpan<float3> positions)
|
||||||
{
|
{
|
||||||
BMIter iter;
|
BMIter iter;
|
||||||
BMVert *v;
|
BMVert *v;
|
||||||
int i;
|
int i;
|
||||||
BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
|
BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
|
||||||
copy_v3_v3(vert_coords[i], v->co);
|
positions[i] = v->co;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float (*BM_mesh_vert_coords_alloc(BMesh *bm, int *r_vert_len))[3]
|
Array<float3> BM_mesh_vert_coords_alloc(BMesh *bm)
|
||||||
{
|
{
|
||||||
float(*vert_coords)[3] = static_cast<float(*)[3]>(
|
Array<float3> positions(bm->totvert);
|
||||||
MEM_mallocN(bm->totvert * sizeof(*vert_coords), __func__));
|
BM_mesh_vert_coords_get(bm, positions);
|
||||||
BM_mesh_vert_coords_get(bm, vert_coords);
|
return positions;
|
||||||
*r_vert_len = bm->totvert;
|
|
||||||
return vert_coords;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BM_mesh_vert_coords_apply(BMesh *bm, const float (*vert_coords)[3])
|
void BM_mesh_vert_coords_apply(BMesh *bm, const float (*vert_coords)[3])
|
||||||
|
|
|
@ -8,6 +8,10 @@
|
||||||
* \ingroup bmesh
|
* \ingroup bmesh
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "BLI_array.hh"
|
||||||
|
#include "BLI_math_vector_types.hh"
|
||||||
|
#include "BLI_span.hh"
|
||||||
|
|
||||||
#include "bmesh_class.hh"
|
#include "bmesh_class.hh"
|
||||||
|
|
||||||
struct BMAllocTemplate;
|
struct BMAllocTemplate;
|
||||||
|
@ -197,8 +201,8 @@ extern const BMAllocTemplate bm_mesh_chunksize_default;
|
||||||
VA_NARGS_CALL_OVERLOAD(_VA_BMALLOC_TEMPLATE_FROM_ME_, __VA_ARGS__)
|
VA_NARGS_CALL_OVERLOAD(_VA_BMALLOC_TEMPLATE_FROM_ME_, __VA_ARGS__)
|
||||||
|
|
||||||
/* Vertex coords access. */
|
/* Vertex coords access. */
|
||||||
void BM_mesh_vert_coords_get(BMesh *bm, float (*vert_coords)[3]);
|
void BM_mesh_vert_coords_get(BMesh *bm, blender::MutableSpan<blender::float3> positions);
|
||||||
float (*BM_mesh_vert_coords_alloc(BMesh *bm, int *r_vert_len))[3];
|
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, const float (*vert_coords)[3]);
|
||||||
void BM_mesh_vert_coords_apply_with_mat4(BMesh *bm,
|
void BM_mesh_vert_coords_apply_with_mat4(BMesh *bm,
|
||||||
const float (*vert_coords)[3],
|
const float (*vert_coords)[3],
|
||||||
|
|
|
@ -90,9 +90,8 @@ static float bm_face_calc_poly_normal_vertex_cos(const BMFace *f,
|
||||||
/**
|
/**
|
||||||
* \brief COMPUTE POLY CENTER (BMFace)
|
* \brief COMPUTE POLY CENTER (BMFace)
|
||||||
*/
|
*/
|
||||||
static void bm_face_calc_poly_center_median_vertex_cos(const BMFace *f,
|
static void bm_face_calc_poly_center_median_vertex_cos(
|
||||||
float r_cent[3],
|
const BMFace *f, float r_cent[3], const blender::Span<blender::float3> vert_positions)
|
||||||
float const (*vertexCos)[3])
|
|
||||||
{
|
{
|
||||||
const BMLoop *l_first, *l_iter;
|
const BMLoop *l_first, *l_iter;
|
||||||
|
|
||||||
|
@ -101,7 +100,7 @@ static void bm_face_calc_poly_center_median_vertex_cos(const BMFace *f,
|
||||||
/* Newell's Method */
|
/* Newell's Method */
|
||||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||||
do {
|
do {
|
||||||
add_v3_v3(r_cent, vertexCos[BM_elem_index_get(l_iter->v)]);
|
add_v3_v3(r_cent, vert_positions[BM_elem_index_get(l_iter->v)]);
|
||||||
} while ((l_iter = l_iter->next) != l_first);
|
} while ((l_iter = l_iter->next) != l_first);
|
||||||
mul_v3_fl(r_cent, 1.0f / f->len);
|
mul_v3_fl(r_cent, 1.0f / f->len);
|
||||||
}
|
}
|
||||||
|
@ -520,7 +519,7 @@ void BM_face_calc_center_bounds(const BMFace *f, float r_cent[3])
|
||||||
void BM_face_calc_center_bounds_vcos(const BMesh *bm,
|
void BM_face_calc_center_bounds_vcos(const BMesh *bm,
|
||||||
const BMFace *f,
|
const BMFace *f,
|
||||||
float r_cent[3],
|
float r_cent[3],
|
||||||
float const (*vertexCos)[3])
|
const blender::Span<blender::float3> vert_positions)
|
||||||
{
|
{
|
||||||
/* must have valid index data */
|
/* must have valid index data */
|
||||||
BLI_assert((bm->elem_index_dirty & BM_VERT) == 0);
|
BLI_assert((bm->elem_index_dirty & BM_VERT) == 0);
|
||||||
|
@ -533,7 +532,7 @@ void BM_face_calc_center_bounds_vcos(const BMesh *bm,
|
||||||
|
|
||||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||||
do {
|
do {
|
||||||
minmax_v3v3_v3(min, max, vertexCos[BM_elem_index_get(l_iter->v)]);
|
minmax_v3v3_v3(min, max, vert_positions[BM_elem_index_get(l_iter->v)]);
|
||||||
} while ((l_iter = l_iter->next) != l_first);
|
} while ((l_iter = l_iter->next) != l_first);
|
||||||
|
|
||||||
mid_v3_v3v3(r_cent, min, max);
|
mid_v3_v3v3(r_cent, min, max);
|
||||||
|
@ -900,13 +899,13 @@ float BM_face_calc_normal_subset(const BMLoop *l_first, const BMLoop *l_last, fl
|
||||||
void BM_face_calc_center_median_vcos(const BMesh *bm,
|
void BM_face_calc_center_median_vcos(const BMesh *bm,
|
||||||
const BMFace *f,
|
const BMFace *f,
|
||||||
float r_cent[3],
|
float r_cent[3],
|
||||||
float const (*vertexCos)[3])
|
const blender::Span<blender::float3> vert_positions)
|
||||||
{
|
{
|
||||||
/* must have valid index data */
|
/* must have valid index data */
|
||||||
BLI_assert((bm->elem_index_dirty & BM_VERT) == 0);
|
BLI_assert((bm->elem_index_dirty & BM_VERT) == 0);
|
||||||
(void)bm;
|
(void)bm;
|
||||||
|
|
||||||
bm_face_calc_poly_center_median_vertex_cos(f, r_cent, vertexCos);
|
bm_face_calc_poly_center_median_vertex_cos(f, r_cent, vert_positions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BM_face_normal_flip_ex(BMesh *bm,
|
void BM_face_normal_flip_ex(BMesh *bm,
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
struct Heap;
|
struct Heap;
|
||||||
|
|
||||||
#include "BLI_compiler_attrs.h"
|
#include "BLI_compiler_attrs.h"
|
||||||
|
#include "BLI_math_vector_types.hh"
|
||||||
|
#include "BLI_span.hh"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For tools that insist on using triangles, ideally we would cache this data.
|
* For tools that insist on using triangles, ideally we would cache this data.
|
||||||
|
@ -128,7 +130,7 @@ void BM_face_calc_center_bounds(const BMFace *f, float r_cent[3]) ATTR_NONNULL()
|
||||||
void BM_face_calc_center_bounds_vcos(const BMesh *bm,
|
void BM_face_calc_center_bounds_vcos(const BMesh *bm,
|
||||||
const BMFace *f,
|
const BMFace *f,
|
||||||
float r_center[3],
|
float r_center[3],
|
||||||
float const (*vertexCos)[3]) ATTR_NONNULL();
|
blender::Span<blender::float3> vert_positions) ATTR_NONNULL();
|
||||||
/**
|
/**
|
||||||
* computes the center of a face, using the mean average
|
* computes the center of a face, using the mean average
|
||||||
*/
|
*/
|
||||||
|
@ -137,7 +139,8 @@ void BM_face_calc_center_median(const BMFace *f, float r_center[3]) ATTR_NONNULL
|
||||||
void BM_face_calc_center_median_vcos(const BMesh *bm,
|
void BM_face_calc_center_median_vcos(const BMesh *bm,
|
||||||
const BMFace *f,
|
const BMFace *f,
|
||||||
float r_center[3],
|
float r_center[3],
|
||||||
float const (*vertexCos)[3]) ATTR_NONNULL();
|
const blender::Span<blender::float3> vert_positions)
|
||||||
|
ATTR_NONNULL();
|
||||||
/**
|
/**
|
||||||
* computes the center of a face, using the mean average
|
* computes the center of a face, using the mean average
|
||||||
* weighted by edge length
|
* weighted by edge length
|
||||||
|
|
|
@ -46,6 +46,9 @@
|
||||||
#include "draw_manager_text.hh"
|
#include "draw_manager_text.hh"
|
||||||
#include "intern/bmesh_polygon.hh"
|
#include "intern/bmesh_polygon.hh"
|
||||||
|
|
||||||
|
using blender::float3;
|
||||||
|
using blender::Span;
|
||||||
|
|
||||||
struct ViewCachedString {
|
struct ViewCachedString {
|
||||||
float vec[3];
|
float vec[3];
|
||||||
union {
|
union {
|
||||||
|
@ -269,8 +272,8 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
|
||||||
float clip_planes[4][4];
|
float clip_planes[4][4];
|
||||||
/* allow for displaying shape keys and deform mods */
|
/* allow for displaying shape keys and deform mods */
|
||||||
BMIter iter;
|
BMIter iter;
|
||||||
const float(*vert_coords)[3] = BKE_mesh_wrapper_vert_coords(mesh);
|
const Span<float3> vert_positions = BKE_mesh_wrapper_vert_coords(mesh);
|
||||||
const bool use_coords = (vert_coords != nullptr);
|
const bool use_coords = !vert_positions.is_empty();
|
||||||
|
|
||||||
/* when 2 or more edge-info options are enabled, space apart */
|
/* when 2 or more edge-info options are enabled, space apart */
|
||||||
short edge_tex_count = 0;
|
short edge_tex_count = 0;
|
||||||
|
@ -329,9 +332,9 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
|
||||||
{
|
{
|
||||||
float v1_clip[3], v2_clip[3];
|
float v1_clip[3], v2_clip[3];
|
||||||
|
|
||||||
if (vert_coords) {
|
if (use_coords) {
|
||||||
copy_v3_v3(v1, vert_coords[BM_elem_index_get(eed->v1)]);
|
copy_v3_v3(v1, vert_positions[BM_elem_index_get(eed->v1)]);
|
||||||
copy_v3_v3(v2, vert_coords[BM_elem_index_get(eed->v2)]);
|
copy_v3_v3(v2, vert_positions[BM_elem_index_get(eed->v2)]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
copy_v3_v3(v1, eed->v1->co);
|
copy_v3_v3(v1, eed->v1->co);
|
||||||
|
@ -373,7 +376,7 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
|
||||||
|
|
||||||
UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGEANG, col);
|
UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGEANG, col);
|
||||||
|
|
||||||
const float(*face_normals)[3] = nullptr;
|
Span<float3> face_normals;
|
||||||
if (use_coords) {
|
if (use_coords) {
|
||||||
BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE);
|
BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE);
|
||||||
face_normals = BKE_mesh_wrapper_face_normals(mesh);
|
face_normals = BKE_mesh_wrapper_face_normals(mesh);
|
||||||
|
@ -395,9 +398,9 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
|
||||||
{
|
{
|
||||||
float v1_clip[3], v2_clip[3];
|
float v1_clip[3], v2_clip[3];
|
||||||
|
|
||||||
if (vert_coords) {
|
if (use_coords) {
|
||||||
copy_v3_v3(v1, vert_coords[BM_elem_index_get(eed->v1)]);
|
copy_v3_v3(v1, vert_positions[BM_elem_index_get(eed->v1)]);
|
||||||
copy_v3_v3(v2, vert_coords[BM_elem_index_get(eed->v2)]);
|
copy_v3_v3(v2, vert_positions[BM_elem_index_get(eed->v2)]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
copy_v3_v3(v1, eed->v1->co);
|
copy_v3_v3(v1, eed->v1->co);
|
||||||
|
@ -462,9 +465,9 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
|
||||||
for (int j = 0; j < f_corner_tris_len; j++) {
|
for (int j = 0; j < f_corner_tris_len; j++) {
|
||||||
|
|
||||||
if (use_coords) {
|
if (use_coords) {
|
||||||
copy_v3_v3(v1, vert_coords[BM_elem_index_get(ltri_array[j][0]->v)]);
|
copy_v3_v3(v1, vert_positions[BM_elem_index_get(ltri_array[j][0]->v)]);
|
||||||
copy_v3_v3(v2, vert_coords[BM_elem_index_get(ltri_array[j][1]->v)]);
|
copy_v3_v3(v2, vert_positions[BM_elem_index_get(ltri_array[j][1]->v)]);
|
||||||
copy_v3_v3(v3, vert_coords[BM_elem_index_get(ltri_array[j][2]->v)]);
|
copy_v3_v3(v3, vert_positions[BM_elem_index_get(ltri_array[j][2]->v)]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
copy_v3_v3(v1, ltri_array[j][0]->v->co);
|
copy_v3_v3(v1, ltri_array[j][0]->v->co);
|
||||||
|
@ -537,7 +540,7 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
|
||||||
/* lazy init center calc */
|
/* lazy init center calc */
|
||||||
if (is_first) {
|
if (is_first) {
|
||||||
if (use_coords) {
|
if (use_coords) {
|
||||||
BM_face_calc_center_bounds_vcos(em->bm, efa, vmid, vert_coords);
|
BM_face_calc_center_bounds_vcos(em->bm, efa, vmid, vert_positions);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BM_face_calc_center_bounds(efa, vmid);
|
BM_face_calc_center_bounds(efa, vmid);
|
||||||
|
@ -545,9 +548,9 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
|
||||||
is_first = false;
|
is_first = false;
|
||||||
}
|
}
|
||||||
if (use_coords) {
|
if (use_coords) {
|
||||||
copy_v3_v3(v1, vert_coords[BM_elem_index_get(loop->prev->v)]);
|
copy_v3_v3(v1, vert_positions[BM_elem_index_get(loop->prev->v)]);
|
||||||
copy_v3_v3(v2, vert_coords[BM_elem_index_get(loop->v)]);
|
copy_v3_v3(v2, vert_positions[BM_elem_index_get(loop->v)]);
|
||||||
copy_v3_v3(v3, vert_coords[BM_elem_index_get(loop->next->v)]);
|
copy_v3_v3(v3, vert_positions[BM_elem_index_get(loop->next->v)]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
copy_v3_v3(v1, loop->prev->v->co);
|
copy_v3_v3(v1, loop->prev->v->co);
|
||||||
|
@ -595,7 +598,7 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
|
||||||
BM_ITER_MESH_INDEX (v, &iter, em->bm, BM_VERTS_OF_MESH, i) {
|
BM_ITER_MESH_INDEX (v, &iter, em->bm, BM_VERTS_OF_MESH, i) {
|
||||||
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
|
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
|
||||||
if (use_coords) {
|
if (use_coords) {
|
||||||
copy_v3_v3(v1, vert_coords[BM_elem_index_get(v)]);
|
copy_v3_v3(v1, vert_positions[BM_elem_index_get(v)]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
copy_v3_v3(v1, v->co);
|
copy_v3_v3(v1, v->co);
|
||||||
|
@ -620,8 +623,8 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
|
||||||
float v1_clip[3], v2_clip[3];
|
float v1_clip[3], v2_clip[3];
|
||||||
|
|
||||||
if (use_coords) {
|
if (use_coords) {
|
||||||
copy_v3_v3(v1, vert_coords[BM_elem_index_get(eed->v1)]);
|
copy_v3_v3(v1, vert_positions[BM_elem_index_get(eed->v1)]);
|
||||||
copy_v3_v3(v2, vert_coords[BM_elem_index_get(eed->v2)]);
|
copy_v3_v3(v2, vert_positions[BM_elem_index_get(eed->v2)]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
copy_v3_v3(v1, eed->v1->co);
|
copy_v3_v3(v1, eed->v1->co);
|
||||||
|
@ -658,7 +661,7 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region,
|
||||||
if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
|
if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
|
||||||
|
|
||||||
if (use_coords) {
|
if (use_coords) {
|
||||||
BM_face_calc_center_median_vcos(em->bm, f, v1, vert_coords);
|
BM_face_calc_center_median_vcos(em->bm, f, v1, vert_positions);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BM_face_calc_center_median(f, v1);
|
BM_face_calc_center_median(f, v1);
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "BLI_compiler_attrs.h"
|
#include "BLI_compiler_attrs.h"
|
||||||
|
#include "BLI_math_vector_types.hh"
|
||||||
|
#include "BLI_span.hh"
|
||||||
|
|
||||||
struct ARegion;
|
struct ARegion;
|
||||||
struct BMBVHTree;
|
struct BMBVHTree;
|
||||||
|
@ -337,7 +339,7 @@ void EDBM_preselect_edgering_update_from_edge(EditMesh_PreSelEdgeRing *psel,
|
||||||
BMesh *bm,
|
BMesh *bm,
|
||||||
BMEdge *eed_start,
|
BMEdge *eed_start,
|
||||||
int previewlines,
|
int previewlines,
|
||||||
const float (*coords)[3]);
|
blender::Span<blender::float3> vert_positions);
|
||||||
|
|
||||||
/* `editmesh_preselect_elem.cc` */
|
/* `editmesh_preselect_elem.cc` */
|
||||||
|
|
||||||
|
@ -356,7 +358,7 @@ void EDBM_preselect_elem_draw(EditMesh_PreSelElem *psel, const float matrix[4][4
|
||||||
void EDBM_preselect_elem_update_from_single(EditMesh_PreSelElem *psel,
|
void EDBM_preselect_elem_update_from_single(EditMesh_PreSelElem *psel,
|
||||||
BMesh *bm,
|
BMesh *bm,
|
||||||
BMElem *ele,
|
BMElem *ele,
|
||||||
const float (*coords)[3]);
|
blender::Span<blender::float3> vert_positions);
|
||||||
|
|
||||||
void EDBM_preselect_elem_update_preview(
|
void EDBM_preselect_elem_update_preview(
|
||||||
EditMesh_PreSelElem *psel, ViewContext *vc, BMesh *bm, BMElem *ele, const int mval[2]);
|
EditMesh_PreSelElem *psel, ViewContext *vc, BMesh *bm, BMElem *ele, const int mval[2]);
|
||||||
|
|
|
@ -198,7 +198,7 @@ struct KnifeBVH {
|
||||||
|
|
||||||
/** Additional per-object data. */
|
/** Additional per-object data. */
|
||||||
struct KnifeObjectInfo {
|
struct KnifeObjectInfo {
|
||||||
const float (*cagecos)[3];
|
Array<float3> positions_cage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optionally allocate triangle indices, these are needed for non-interactive knife
|
* Optionally allocate triangle indices, these are needed for non-interactive knife
|
||||||
|
@ -206,7 +206,7 @@ struct KnifeObjectInfo {
|
||||||
* Using these indices the it's possible to access `cagecos` even if the face has been cut
|
* Using these indices the it's possible to access `cagecos` even if the face has been cut
|
||||||
* and the loops in `em->looptris` no longer refer to the original triangles, see: #97153.
|
* and the loops in `em->looptris` no longer refer to the original triangles, see: #97153.
|
||||||
*/
|
*/
|
||||||
const int (*tri_indices)[3];
|
Array<int3> tri_indices;
|
||||||
|
|
||||||
/** Only assigned for convenient access. */
|
/** Only assigned for convenient access. */
|
||||||
BMEditMesh *em;
|
BMEditMesh *em;
|
||||||
|
@ -227,7 +227,7 @@ struct KnifeTool_OpData {
|
||||||
Vector<Object *> objects;
|
Vector<Object *> objects;
|
||||||
|
|
||||||
/** Array `objects_len` length of additional per-object data. */
|
/** Array `objects_len` length of additional per-object data. */
|
||||||
KnifeObjectInfo *objects_info;
|
Array<KnifeObjectInfo> objects_info;
|
||||||
|
|
||||||
MemArena *arena;
|
MemArena *arena;
|
||||||
|
|
||||||
|
@ -1163,7 +1163,7 @@ static const int *knife_bm_tri_index_get(const KnifeTool_OpData *kcd,
|
||||||
int tri_index_buf[3])
|
int tri_index_buf[3])
|
||||||
{
|
{
|
||||||
const KnifeObjectInfo *obinfo = &kcd->objects_info[ob_index];
|
const KnifeObjectInfo *obinfo = &kcd->objects_info[ob_index];
|
||||||
if (obinfo->tri_indices) {
|
if (!obinfo->tri_indices.is_empty()) {
|
||||||
return obinfo->tri_indices[tri_index];
|
return obinfo->tri_indices[tri_index];
|
||||||
}
|
}
|
||||||
const std::array<BMLoop *, 3> <ri = obinfo->em->looptris[tri_index];
|
const std::array<BMLoop *, 3> <ri = obinfo->em->looptris[tri_index];
|
||||||
|
@ -1182,7 +1182,7 @@ static void knife_bm_tri_cagecos_get(const KnifeTool_OpData *kcd,
|
||||||
int tri_ind_buf[3];
|
int tri_ind_buf[3];
|
||||||
const int *tri_ind = knife_bm_tri_index_get(kcd, ob_index, tri_index, tri_ind_buf);
|
const int *tri_ind = knife_bm_tri_index_get(kcd, ob_index, tri_index, tri_ind_buf);
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
copy_v3_v3(cos[i], obinfo->cagecos[tri_ind[i]]);
|
copy_v3_v3(cos[i], obinfo->positions_cage[tri_ind[i]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1689,7 +1689,7 @@ static KnifeVert *get_bm_knife_vert(KnifeTool_OpData *kcd, BMVert *v, int ob_ind
|
||||||
BMFace *f;
|
BMFace *f;
|
||||||
|
|
||||||
if (BM_elem_index_get(v) >= 0) {
|
if (BM_elem_index_get(v) >= 0) {
|
||||||
cageco = kcd->objects_info[ob_index].cagecos[BM_elem_index_get(v)];
|
cageco = kcd->objects_info[ob_index].positions_cage[BM_elem_index_get(v)];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cageco = v->co;
|
cageco = v->co;
|
||||||
|
@ -2581,10 +2581,10 @@ static void calc_ortho_extent(KnifeTool_OpData *kcd)
|
||||||
ob = kcd->objects[ob_index];
|
ob = kcd->objects[ob_index];
|
||||||
em = BKE_editmesh_from_object(ob);
|
em = BKE_editmesh_from_object(ob);
|
||||||
|
|
||||||
const float(*cagecos)[3] = kcd->objects_info[ob_index].cagecos;
|
const Span<float3> positions_cage = kcd->objects_info[ob_index].positions_cage;
|
||||||
if (cagecos) {
|
if (!positions_cage.is_empty()) {
|
||||||
for (int i = 0; i < em->bm->totvert; i++) {
|
for (int i = 0; i < em->bm->totvert; i++) {
|
||||||
copy_v3_v3(ws, cagecos[i]);
|
copy_v3_v3(ws, positions_cage[i]);
|
||||||
mul_m4_v3(ob->object_to_world().ptr(), ws);
|
mul_m4_v3(ob->object_to_world().ptr(), ws);
|
||||||
minmax_v3v3_v3(min, max, ws);
|
minmax_v3v3_v3(min, max, ws);
|
||||||
}
|
}
|
||||||
|
@ -3955,28 +3955,20 @@ static void knifetool_init_obinfo(KnifeTool_OpData *kcd,
|
||||||
|
|
||||||
KnifeObjectInfo *obinfo = &kcd->objects_info[ob_index];
|
KnifeObjectInfo *obinfo = &kcd->objects_info[ob_index];
|
||||||
obinfo->em = em_eval;
|
obinfo->em = em_eval;
|
||||||
obinfo->cagecos = (const float(*)[3])BKE_editmesh_vert_coords_alloc(
|
obinfo->positions_cage = BKE_editmesh_vert_coords_alloc(
|
||||||
kcd->vc.depsgraph, em_eval, scene_eval, obedit_eval, nullptr);
|
kcd->vc.depsgraph, em_eval, scene_eval, obedit_eval);
|
||||||
|
|
||||||
if (use_tri_indices) {
|
if (use_tri_indices) {
|
||||||
int(*tri_indices)[3] = static_cast<int(*)[3]>(
|
obinfo->tri_indices.reinitialize(em_eval->looptris.size());
|
||||||
MEM_mallocN(sizeof(int[3]) * em_eval->looptris.size(), __func__));
|
|
||||||
for (int i = 0; i < em_eval->looptris.size(); i++) {
|
for (int i = 0; i < em_eval->looptris.size(); i++) {
|
||||||
const std::array<BMLoop *, 3> <ri = em_eval->looptris[i];
|
const std::array<BMLoop *, 3> <ri = em_eval->looptris[i];
|
||||||
tri_indices[i][0] = BM_elem_index_get(ltri[0]->v);
|
obinfo->tri_indices[i][0] = BM_elem_index_get(ltri[0]->v);
|
||||||
tri_indices[i][1] = BM_elem_index_get(ltri[1]->v);
|
obinfo->tri_indices[i][1] = BM_elem_index_get(ltri[1]->v);
|
||||||
tri_indices[i][2] = BM_elem_index_get(ltri[2]->v);
|
obinfo->tri_indices[i][2] = BM_elem_index_get(ltri[2]->v);
|
||||||
}
|
}
|
||||||
obinfo->tri_indices = tri_indices;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void knifetool_free_obinfo(KnifeTool_OpData *kcd, int ob_index)
|
|
||||||
{
|
|
||||||
MEM_SAFE_FREE(kcd->objects_info[ob_index].cagecos);
|
|
||||||
MEM_SAFE_FREE(kcd->objects_info[ob_index].tri_indices);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
@ -4032,8 +4024,7 @@ static void knifetool_init(ViewContext *vc,
|
||||||
|
|
||||||
Object *ob;
|
Object *ob;
|
||||||
BMEditMesh *em;
|
BMEditMesh *em;
|
||||||
kcd->objects_info = static_cast<KnifeObjectInfo *>(
|
kcd->objects_info.reinitialize(kcd->objects.size());
|
||||||
MEM_callocN(sizeof(*kcd->objects_info) * kcd->objects.size(), "knife cagecos"));
|
|
||||||
for (int ob_index = 0; ob_index < kcd->objects.size(); ob_index++) {
|
for (int ob_index = 0; ob_index < kcd->objects.size(); ob_index++) {
|
||||||
ob = kcd->objects[ob_index];
|
ob = kcd->objects[ob_index];
|
||||||
em = BKE_editmesh_from_object(ob);
|
em = BKE_editmesh_from_object(ob);
|
||||||
|
@ -4140,10 +4131,6 @@ static void knifetool_exit_ex(KnifeTool_OpData *kcd)
|
||||||
ED_region_tag_redraw(kcd->region);
|
ED_region_tag_redraw(kcd->region);
|
||||||
|
|
||||||
/* Knife BVH cleanup. */
|
/* Knife BVH cleanup. */
|
||||||
for (int i = 0; i < kcd->objects.size(); i++) {
|
|
||||||
knifetool_free_obinfo(kcd, i);
|
|
||||||
}
|
|
||||||
MEM_freeN((void *)kcd->objects_info);
|
|
||||||
knife_bvh_free(kcd);
|
knife_bvh_free(kcd);
|
||||||
|
|
||||||
/* Line-hits cleanup. */
|
/* Line-hits cleanup. */
|
||||||
|
|
|
@ -42,6 +42,9 @@
|
||||||
|
|
||||||
#include "mesh_intern.hh" /* own include */
|
#include "mesh_intern.hh" /* own include */
|
||||||
|
|
||||||
|
using blender::Array;
|
||||||
|
using blender::float3;
|
||||||
|
using blender::Span;
|
||||||
using blender::Vector;
|
using blender::Vector;
|
||||||
|
|
||||||
#define SUBD_SMOOTH_MAX 4.0f
|
#define SUBD_SMOOTH_MAX 4.0f
|
||||||
|
@ -50,8 +53,9 @@ using blender::Vector;
|
||||||
/* ringsel operator */
|
/* ringsel operator */
|
||||||
|
|
||||||
struct MeshCoordsCache {
|
struct MeshCoordsCache {
|
||||||
bool is_init, is_alloc;
|
bool is_init;
|
||||||
const float (*coords)[3];
|
Array<float3> allocated_vert_positions;
|
||||||
|
Span<float3> vert_positions;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* struct for properties used while drawing */
|
/* struct for properties used while drawing */
|
||||||
|
@ -67,7 +71,7 @@ struct RingSelOpData {
|
||||||
|
|
||||||
Vector<Base *> bases;
|
Vector<Base *> bases;
|
||||||
|
|
||||||
MeshCoordsCache *geom_cache;
|
Array<MeshCoordsCache> geom_cache;
|
||||||
|
|
||||||
/* These values switch objects based on the object under the cursor. */
|
/* These values switch objects based on the object under the cursor. */
|
||||||
uint base_index;
|
uint base_index;
|
||||||
|
@ -138,13 +142,13 @@ static void ringsel_find_edge(RingSelOpData *lcd, const int previewlines)
|
||||||
Scene *scene_eval = (Scene *)DEG_get_evaluated_id(lcd->vc.depsgraph, &lcd->vc.scene->id);
|
Scene *scene_eval = (Scene *)DEG_get_evaluated_id(lcd->vc.depsgraph, &lcd->vc.scene->id);
|
||||||
Object *ob_eval = DEG_get_evaluated_object(lcd->vc.depsgraph, lcd->ob);
|
Object *ob_eval = DEG_get_evaluated_object(lcd->vc.depsgraph, lcd->ob);
|
||||||
BMEditMesh *em_eval = BKE_editmesh_from_object(ob_eval);
|
BMEditMesh *em_eval = BKE_editmesh_from_object(ob_eval);
|
||||||
gcache->coords = BKE_editmesh_vert_coords_when_deformed(
|
gcache->vert_positions = BKE_editmesh_vert_coords_when_deformed(
|
||||||
lcd->vc.depsgraph, em_eval, scene_eval, ob_eval, nullptr, &gcache->is_alloc);
|
lcd->vc.depsgraph, em_eval, scene_eval, ob_eval, gcache->allocated_vert_positions);
|
||||||
gcache->is_init = true;
|
gcache->is_init = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
EDBM_preselect_edgering_update_from_edge(
|
EDBM_preselect_edgering_update_from_edge(
|
||||||
lcd->presel_edgering, lcd->em->bm, lcd->eed, previewlines, gcache->coords);
|
lcd->presel_edgering, lcd->em->bm, lcd->eed, previewlines, gcache->vert_positions);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
EDBM_preselect_edgering_clear(lcd->presel_edgering);
|
EDBM_preselect_edgering_clear(lcd->presel_edgering);
|
||||||
|
@ -256,14 +260,6 @@ static void ringsel_exit(bContext * /*C*/, wmOperator *op)
|
||||||
|
|
||||||
EDBM_preselect_edgering_destroy(lcd->presel_edgering);
|
EDBM_preselect_edgering_destroy(lcd->presel_edgering);
|
||||||
|
|
||||||
for (const int i : lcd->bases.index_range()) {
|
|
||||||
MeshCoordsCache *gcache = &lcd->geom_cache[i];
|
|
||||||
if (gcache->is_alloc) {
|
|
||||||
MEM_freeN((void *)gcache->coords);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MEM_freeN(lcd->geom_cache);
|
|
||||||
|
|
||||||
ED_region_tag_redraw(lcd->region);
|
ED_region_tag_redraw(lcd->region);
|
||||||
|
|
||||||
MEM_delete(lcd);
|
MEM_delete(lcd);
|
||||||
|
@ -428,8 +424,7 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
|
||||||
RingSelOpData *lcd = static_cast<RingSelOpData *>(op->customdata);
|
RingSelOpData *lcd = static_cast<RingSelOpData *>(op->customdata);
|
||||||
|
|
||||||
lcd->bases = std::move(bases);
|
lcd->bases = std::move(bases);
|
||||||
lcd->geom_cache = static_cast<MeshCoordsCache *>(
|
lcd->geom_cache.reinitialize(lcd->bases.size());
|
||||||
MEM_callocN(sizeof(*lcd->geom_cache) * lcd->bases.size(), __func__));
|
|
||||||
|
|
||||||
if (is_interactive) {
|
if (is_interactive) {
|
||||||
copy_v2_v2_int(lcd->vc.mval, event->mval);
|
copy_v2_v2_int(lcd->vc.mval, event->mval);
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
|
|
||||||
#include "UI_resources.hh"
|
#include "UI_resources.hh"
|
||||||
|
|
||||||
|
using blender::float3;
|
||||||
|
using blender::Span;
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Mesh Edge Ring Pre-Select
|
/** \name Mesh Edge Ring Pre-Select
|
||||||
* Public API:
|
* Public API:
|
||||||
|
@ -34,13 +37,15 @@
|
||||||
*
|
*
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
static void edgering_vcos_get(BMVert *v[2][2], float r_cos[2][2][3], const float (*coords)[3])
|
static void edgering_vcos_get(BMVert *v[2][2],
|
||||||
|
float r_cos[2][2][3],
|
||||||
|
const Span<float3> vert_positions)
|
||||||
{
|
{
|
||||||
if (coords) {
|
if (!vert_positions.is_empty()) {
|
||||||
int j, k;
|
int j, k;
|
||||||
for (j = 0; j < 2; j++) {
|
for (j = 0; j < 2; j++) {
|
||||||
for (k = 0; k < 2; k++) {
|
for (k = 0; k < 2; k++) {
|
||||||
copy_v3_v3(r_cos[j][k], coords[BM_elem_index_get(v[j][k])]);
|
copy_v3_v3(r_cos[j][k], vert_positions[BM_elem_index_get(v[j][k])]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,12 +59,14 @@ static void edgering_vcos_get(BMVert *v[2][2], float r_cos[2][2][3], const float
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void edgering_vcos_get_pair(BMVert *v[2], float r_cos[2][3], const float (*coords)[3])
|
static void edgering_vcos_get_pair(BMVert *v[2],
|
||||||
|
float r_cos[2][3],
|
||||||
|
const Span<float3> vert_positions)
|
||||||
{
|
{
|
||||||
if (coords) {
|
if (!vert_positions.is_empty()) {
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < 2; j++) {
|
for (j = 0; j < 2; j++) {
|
||||||
copy_v3_v3(r_cos[j], coords[BM_elem_index_get(v[j])]);
|
copy_v3_v3(r_cos[j], vert_positions[BM_elem_index_get(v[j])]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -204,11 +211,12 @@ void EDBM_preselect_edgering_draw(EditMesh_PreSelEdgeRing *psel, const float mat
|
||||||
GPU_blend(GPU_BLEND_NONE);
|
GPU_blend(GPU_BLEND_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void view3d_preselect_mesh_edgering_update_verts_from_edge(EditMesh_PreSelEdgeRing *psel,
|
static void view3d_preselect_mesh_edgering_update_verts_from_edge(
|
||||||
BMesh * /*bm*/,
|
EditMesh_PreSelEdgeRing *psel,
|
||||||
BMEdge *eed_start,
|
BMesh * /*bm*/,
|
||||||
int previewlines,
|
BMEdge *eed_start,
|
||||||
const float (*coords)[3])
|
int previewlines,
|
||||||
|
const Span<float3> vert_positions)
|
||||||
{
|
{
|
||||||
float v_cos[2][3];
|
float v_cos[2][3];
|
||||||
float(*verts)[3];
|
float(*verts)[3];
|
||||||
|
@ -216,7 +224,7 @@ static void view3d_preselect_mesh_edgering_update_verts_from_edge(EditMesh_PreSe
|
||||||
|
|
||||||
verts = static_cast<float(*)[3]>(MEM_mallocN(sizeof(*psel->verts) * previewlines, __func__));
|
verts = static_cast<float(*)[3]>(MEM_mallocN(sizeof(*psel->verts) * previewlines, __func__));
|
||||||
|
|
||||||
edgering_vcos_get_pair(&eed_start->v1, v_cos, coords);
|
edgering_vcos_get_pair(&eed_start->v1, v_cos, vert_positions);
|
||||||
|
|
||||||
for (i = 1; i <= previewlines; i++) {
|
for (i = 1; i <= previewlines; i++) {
|
||||||
const float fac = (i / (float(previewlines) + 1));
|
const float fac = (i / (float(previewlines) + 1));
|
||||||
|
@ -228,11 +236,12 @@ static void view3d_preselect_mesh_edgering_update_verts_from_edge(EditMesh_PreSe
|
||||||
psel->verts_len = previewlines;
|
psel->verts_len = previewlines;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void view3d_preselect_mesh_edgering_update_edges_from_edge(EditMesh_PreSelEdgeRing *psel,
|
static void view3d_preselect_mesh_edgering_update_edges_from_edge(
|
||||||
BMesh *bm,
|
EditMesh_PreSelEdgeRing *psel,
|
||||||
BMEdge *eed_start,
|
BMesh *bm,
|
||||||
int previewlines,
|
BMEdge *eed_start,
|
||||||
const float (*coords)[3])
|
int previewlines,
|
||||||
|
const Span<float3> vert_positions)
|
||||||
{
|
{
|
||||||
BMWalker walker;
|
BMWalker walker;
|
||||||
BMEdge *eed, *eed_last;
|
BMEdge *eed, *eed_last;
|
||||||
|
@ -291,7 +300,7 @@ static void view3d_preselect_mesh_edgering_update_edges_from_edge(EditMesh_PreSe
|
||||||
const float fac = (i / (float(previewlines) + 1));
|
const float fac = (i / (float(previewlines) + 1));
|
||||||
float v_cos[2][2][3];
|
float v_cos[2][2][3];
|
||||||
|
|
||||||
edgering_vcos_get(v, v_cos, coords);
|
edgering_vcos_get(v, v_cos, vert_positions);
|
||||||
|
|
||||||
interp_v3_v3v3(edges[tot][0], v_cos[0][0], v_cos[0][1], fac);
|
interp_v3_v3v3(edges[tot][0], v_cos[0][0], v_cos[0][1], fac);
|
||||||
interp_v3_v3v3(edges[tot][1], v_cos[1][0], v_cos[1][1], fac);
|
interp_v3_v3v3(edges[tot][1], v_cos[1][0], v_cos[1][1], fac);
|
||||||
|
@ -322,7 +331,7 @@ static void view3d_preselect_mesh_edgering_update_edges_from_edge(EditMesh_PreSe
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
edgering_vcos_get(v, v_cos, coords);
|
edgering_vcos_get(v, v_cos, vert_positions);
|
||||||
|
|
||||||
interp_v3_v3v3(edges[tot][0], v_cos[0][0], v_cos[0][1], fac);
|
interp_v3_v3v3(edges[tot][0], v_cos[0][0], v_cos[0][1], fac);
|
||||||
interp_v3_v3v3(edges[tot][1], v_cos[1][0], v_cos[1][1], fac);
|
interp_v3_v3v3(edges[tot][1], v_cos[1][0], v_cos[1][1], fac);
|
||||||
|
@ -340,21 +349,21 @@ void EDBM_preselect_edgering_update_from_edge(EditMesh_PreSelEdgeRing *psel,
|
||||||
BMesh *bm,
|
BMesh *bm,
|
||||||
BMEdge *eed_start,
|
BMEdge *eed_start,
|
||||||
int previewlines,
|
int previewlines,
|
||||||
const float (*coords)[3])
|
const Span<float3> vert_positions)
|
||||||
{
|
{
|
||||||
EDBM_preselect_edgering_clear(psel);
|
EDBM_preselect_edgering_clear(psel);
|
||||||
|
|
||||||
if (coords) {
|
if (!vert_positions.is_empty()) {
|
||||||
BM_mesh_elem_index_ensure(bm, BM_VERT);
|
BM_mesh_elem_index_ensure(bm, BM_VERT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BM_edge_is_any_face_len_test(eed_start, 4)) {
|
if (BM_edge_is_any_face_len_test(eed_start, 4)) {
|
||||||
view3d_preselect_mesh_edgering_update_edges_from_edge(
|
view3d_preselect_mesh_edgering_update_edges_from_edge(
|
||||||
psel, bm, eed_start, previewlines, coords);
|
psel, bm, eed_start, previewlines, vert_positions);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
view3d_preselect_mesh_edgering_update_verts_from_edge(
|
view3d_preselect_mesh_edgering_update_verts_from_edge(
|
||||||
psel, bm, eed_start, previewlines, coords);
|
psel, bm, eed_start, previewlines, vert_positions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
#include "ED_mesh.hh"
|
#include "ED_mesh.hh"
|
||||||
#include "ED_view3d.hh"
|
#include "ED_view3d.hh"
|
||||||
|
|
||||||
|
using blender::float3;
|
||||||
|
using blender::Span;
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Mesh Element Pre-Select
|
/** \name Mesh Element Pre-Select
|
||||||
* Public API:
|
* Public API:
|
||||||
|
@ -33,21 +36,21 @@
|
||||||
*
|
*
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
static void vcos_get(BMVert *v, float r_co[3], const float (*coords)[3])
|
static void vcos_get(BMVert *v, float r_co[3], const Span<float3> vert_positions)
|
||||||
{
|
{
|
||||||
if (coords) {
|
if (!vert_positions.is_empty()) {
|
||||||
copy_v3_v3(r_co, coords[BM_elem_index_get(v)]);
|
copy_v3_v3(r_co, vert_positions[BM_elem_index_get(v)]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
copy_v3_v3(r_co, v->co);
|
copy_v3_v3(r_co, v->co);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vcos_get_pair(BMVert *v[2], float r_cos[2][3], const float (*coords)[3])
|
static void vcos_get_pair(BMVert *v[2], float r_cos[2][3], const Span<float3> vert_positions)
|
||||||
{
|
{
|
||||||
if (coords) {
|
if (!vert_positions.is_empty()) {
|
||||||
for (int j = 0; j < 2; j++) {
|
for (int j = 0; j < 2; j++) {
|
||||||
copy_v3_v3(r_cos[j], coords[BM_elem_index_get(v[j])]);
|
copy_v3_v3(r_cos[j], vert_positions[BM_elem_index_get(v[j])]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -198,10 +201,10 @@ void EDBM_preselect_elem_draw(EditMesh_PreSelElem *psel, const float matrix[4][4
|
||||||
static void view3d_preselect_mesh_elem_update_from_vert(EditMesh_PreSelElem *psel,
|
static void view3d_preselect_mesh_elem_update_from_vert(EditMesh_PreSelElem *psel,
|
||||||
BMesh * /*bm*/,
|
BMesh * /*bm*/,
|
||||||
BMVert *eve,
|
BMVert *eve,
|
||||||
const float (*coords)[3])
|
const Span<float3> vert_positions)
|
||||||
{
|
{
|
||||||
float(*verts)[3] = static_cast<float(*)[3]>(MEM_mallocN(sizeof(*psel->verts), __func__));
|
float(*verts)[3] = static_cast<float(*)[3]>(MEM_mallocN(sizeof(*psel->verts), __func__));
|
||||||
vcos_get(eve, verts[0], coords);
|
vcos_get(eve, verts[0], vert_positions);
|
||||||
psel->verts = verts;
|
psel->verts = verts;
|
||||||
psel->verts_len = 1;
|
psel->verts_len = 1;
|
||||||
}
|
}
|
||||||
|
@ -209,10 +212,10 @@ static void view3d_preselect_mesh_elem_update_from_vert(EditMesh_PreSelElem *pse
|
||||||
static void view3d_preselect_mesh_elem_update_from_edge(EditMesh_PreSelElem *psel,
|
static void view3d_preselect_mesh_elem_update_from_edge(EditMesh_PreSelElem *psel,
|
||||||
BMesh * /*bm*/,
|
BMesh * /*bm*/,
|
||||||
BMEdge *eed,
|
BMEdge *eed,
|
||||||
const float (*coords)[3])
|
const Span<float3> vert_positions)
|
||||||
{
|
{
|
||||||
float(*edges)[2][3] = static_cast<float(*)[2][3]>(MEM_mallocN(sizeof(*psel->edges), __func__));
|
float(*edges)[2][3] = static_cast<float(*)[2][3]>(MEM_mallocN(sizeof(*psel->edges), __func__));
|
||||||
vcos_get_pair(&eed->v1, edges[0], coords);
|
vcos_get_pair(&eed->v1, edges[0], vert_positions);
|
||||||
psel->edges = edges;
|
psel->edges = edges;
|
||||||
psel->edges_len = 1;
|
psel->edges_len = 1;
|
||||||
}
|
}
|
||||||
|
@ -298,7 +301,7 @@ static void view3d_preselect_update_preview_triangle_from_face(EditMesh_PreSelEl
|
||||||
l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
|
l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
do {
|
do {
|
||||||
vcos_get_pair(&l_iter->e->v1, preview_lines[i++], nullptr);
|
vcos_get_pair(&l_iter->e->v1, preview_lines[i++], {});
|
||||||
} while ((l_iter = l_iter->next) != l_first);
|
} while ((l_iter = l_iter->next) != l_first);
|
||||||
psel->preview_lines = preview_lines;
|
psel->preview_lines = preview_lines;
|
||||||
psel->preview_lines_len = efa->len;
|
psel->preview_lines_len = efa->len;
|
||||||
|
@ -336,7 +339,7 @@ static void view3d_preselect_update_preview_triangle_from_edge(
|
||||||
static void view3d_preselect_mesh_elem_update_from_face(EditMesh_PreSelElem *psel,
|
static void view3d_preselect_mesh_elem_update_from_face(EditMesh_PreSelElem *psel,
|
||||||
BMesh * /*bm*/,
|
BMesh * /*bm*/,
|
||||||
BMFace *efa,
|
BMFace *efa,
|
||||||
const float (*coords)[3])
|
const Span<float3> vert_positions)
|
||||||
{
|
{
|
||||||
float(*edges)[2][3] = static_cast<float(*)[2][3]>(
|
float(*edges)[2][3] = static_cast<float(*)[2][3]>(
|
||||||
MEM_mallocN(sizeof(*psel->edges) * efa->len, __func__));
|
MEM_mallocN(sizeof(*psel->edges) * efa->len, __func__));
|
||||||
|
@ -344,7 +347,7 @@ static void view3d_preselect_mesh_elem_update_from_face(EditMesh_PreSelElem *pse
|
||||||
l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
|
l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
do {
|
do {
|
||||||
vcos_get_pair(&l_iter->e->v1, edges[i++], coords);
|
vcos_get_pair(&l_iter->e->v1, edges[i++], vert_positions);
|
||||||
} while ((l_iter = l_iter->next) != l_first);
|
} while ((l_iter = l_iter->next) != l_first);
|
||||||
psel->edges = edges;
|
psel->edges = edges;
|
||||||
psel->edges_len = efa->len;
|
psel->edges_len = efa->len;
|
||||||
|
@ -353,23 +356,23 @@ static void view3d_preselect_mesh_elem_update_from_face(EditMesh_PreSelElem *pse
|
||||||
void EDBM_preselect_elem_update_from_single(EditMesh_PreSelElem *psel,
|
void EDBM_preselect_elem_update_from_single(EditMesh_PreSelElem *psel,
|
||||||
BMesh *bm,
|
BMesh *bm,
|
||||||
BMElem *ele,
|
BMElem *ele,
|
||||||
const float (*coords)[3])
|
const Span<float3> vert_positions)
|
||||||
{
|
{
|
||||||
EDBM_preselect_elem_clear(psel);
|
EDBM_preselect_elem_clear(psel);
|
||||||
|
|
||||||
if (coords) {
|
if (!vert_positions.is_empty()) {
|
||||||
BM_mesh_elem_index_ensure(bm, BM_VERT);
|
BM_mesh_elem_index_ensure(bm, BM_VERT);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ele->head.htype) {
|
switch (ele->head.htype) {
|
||||||
case BM_VERT:
|
case BM_VERT:
|
||||||
view3d_preselect_mesh_elem_update_from_vert(psel, bm, (BMVert *)ele, coords);
|
view3d_preselect_mesh_elem_update_from_vert(psel, bm, (BMVert *)ele, vert_positions);
|
||||||
break;
|
break;
|
||||||
case BM_EDGE:
|
case BM_EDGE:
|
||||||
view3d_preselect_mesh_elem_update_from_edge(psel, bm, (BMEdge *)ele, coords);
|
view3d_preselect_mesh_elem_update_from_edge(psel, bm, (BMEdge *)ele, vert_positions);
|
||||||
break;
|
break;
|
||||||
case BM_FACE:
|
case BM_FACE:
|
||||||
view3d_preselect_mesh_elem_update_from_face(psel, bm, (BMFace *)ele, coords);
|
view3d_preselect_mesh_elem_update_from_face(psel, bm, (BMFace *)ele, vert_positions);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BLI_assert(0);
|
BLI_assert(0);
|
||||||
|
|
|
@ -69,6 +69,7 @@
|
||||||
/* use bmesh operator flags for a few operators */
|
/* use bmesh operator flags for a few operators */
|
||||||
#define BMO_ELE_TAG 1
|
#define BMO_ELE_TAG 1
|
||||||
|
|
||||||
|
using blender::float3;
|
||||||
using blender::Span;
|
using blender::Span;
|
||||||
using blender::Vector;
|
using blender::Vector;
|
||||||
|
|
||||||
|
@ -1079,16 +1080,16 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
|
||||||
copy_m3_m4(imat3, obedit->object_to_world().ptr());
|
copy_m3_m4(imat3, obedit->object_to_world().ptr());
|
||||||
invert_m3(imat3);
|
invert_m3(imat3);
|
||||||
|
|
||||||
const float(*coords)[3] = nullptr;
|
Span<float3> vert_positions;
|
||||||
{
|
{
|
||||||
Object *obedit_eval = DEG_get_evaluated_object(vc->depsgraph, obedit);
|
Object *obedit_eval = DEG_get_evaluated_object(vc->depsgraph, obedit);
|
||||||
Mesh *mesh_eval = BKE_object_get_editmesh_eval_cage(obedit_eval);
|
Mesh *mesh_eval = BKE_object_get_editmesh_eval_cage(obedit_eval);
|
||||||
if (BKE_mesh_wrapper_vert_len(mesh_eval) == bm->totvert) {
|
if (BKE_mesh_wrapper_vert_len(mesh_eval) == bm->totvert) {
|
||||||
coords = BKE_mesh_wrapper_vert_coords(mesh_eval);
|
vert_positions = BKE_mesh_wrapper_vert_coords(mesh_eval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (coords != nullptr) {
|
if (!vert_positions.is_empty()) {
|
||||||
BM_mesh_elem_index_ensure(bm, BM_VERT);
|
BM_mesh_elem_index_ensure(bm, BM_VERT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1103,7 +1104,8 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
|
||||||
float point[3];
|
float point[3];
|
||||||
mul_v3_m4v3(point,
|
mul_v3_m4v3(point,
|
||||||
obedit->object_to_world().ptr(),
|
obedit->object_to_world().ptr(),
|
||||||
coords ? coords[BM_elem_index_get(v)] : v->co);
|
!vert_positions.is_empty() ? vert_positions[BM_elem_index_get(v)] :
|
||||||
|
v->co);
|
||||||
const float dist_sq_test = dist_squared_to_ray_v3_normalized(
|
const float dist_sq_test = dist_squared_to_ray_v3_normalized(
|
||||||
ray_origin, ray_direction, point);
|
ray_origin, ray_direction, point);
|
||||||
if (dist_sq_test < dist_sq_best_vert) {
|
if (dist_sq_test < dist_sq_best_vert) {
|
||||||
|
@ -1125,9 +1127,10 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
|
||||||
const float dist_sq_test = dist_squared_ray_to_seg_v3(
|
const float dist_sq_test = dist_squared_ray_to_seg_v3(
|
||||||
ray_origin, ray_direction, e->v1->co, e->v2->co, point, &depth);
|
ray_origin, ray_direction, e->v1->co, e->v2->co, point, &depth);
|
||||||
#else
|
#else
|
||||||
if (coords) {
|
if (!vert_positions.is_empty()) {
|
||||||
mid_v3_v3v3(
|
mid_v3_v3v3(point,
|
||||||
point, coords[BM_elem_index_get(e->v1)], coords[BM_elem_index_get(e->v2)]);
|
vert_positions[BM_elem_index_get(e->v1)],
|
||||||
|
vert_positions[BM_elem_index_get(e->v2)]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mid_v3_v3v3(point, e->v1->co, e->v2->co);
|
mid_v3_v3v3(point, e->v1->co, e->v2->co);
|
||||||
|
@ -1159,7 +1162,7 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
|
||||||
float point[3];
|
float point[3];
|
||||||
mul_v3_m4v3(point,
|
mul_v3_m4v3(point,
|
||||||
obedit->object_to_world().ptr(),
|
obedit->object_to_world().ptr(),
|
||||||
coords ? coords[BM_elem_index_get(v)] : v->co);
|
!vert_positions.is_empty() ? vert_positions[BM_elem_index_get(v)] : v->co);
|
||||||
const float dist_sq_test = dist_squared_to_ray_v3_normalized(
|
const float dist_sq_test = dist_squared_to_ray_v3_normalized(
|
||||||
ray_origin, ray_direction, point);
|
ray_origin, ray_direction, point);
|
||||||
if (dist_sq_test < dist_sq_best_vert) {
|
if (dist_sq_test < dist_sq_best_vert) {
|
||||||
|
@ -1182,9 +1185,10 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
|
||||||
BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
|
BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
|
||||||
if (BM_elem_flag_test(e, BM_ELEM_HIDDEN) == false) {
|
if (BM_elem_flag_test(e, BM_ELEM_HIDDEN) == false) {
|
||||||
float point[3];
|
float point[3];
|
||||||
if (coords) {
|
if (!vert_positions.is_empty()) {
|
||||||
mid_v3_v3v3(
|
mid_v3_v3v3(point,
|
||||||
point, coords[BM_elem_index_get(e->v1)], coords[BM_elem_index_get(e->v2)]);
|
vert_positions[BM_elem_index_get(e->v1)],
|
||||||
|
vert_positions[BM_elem_index_get(e->v2)]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mid_v3_v3v3(point, e->v1->co, e->v2->co);
|
mid_v3_v3v3(point, e->v1->co, e->v2->co);
|
||||||
|
@ -1212,8 +1216,8 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc,
|
||||||
BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
|
BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
|
||||||
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN) == false) {
|
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN) == false) {
|
||||||
float point[3];
|
float point[3];
|
||||||
if (coords) {
|
if (!vert_positions.is_empty()) {
|
||||||
BM_face_calc_center_median_vcos(bm, f, point, coords);
|
BM_face_calc_center_median_vcos(bm, f, point, vert_positions);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BM_face_calc_center_median(f, point);
|
BM_face_calc_center_median(f, point);
|
||||||
|
|
|
@ -324,7 +324,8 @@ XFormObjectData *data_xform_create_ex(ID *id, bool is_edit_mode)
|
||||||
MEM_mallocN(sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__));
|
MEM_mallocN(sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__));
|
||||||
memset(xod, 0x0, sizeof(*xod));
|
memset(xod, 0x0, sizeof(*xod));
|
||||||
|
|
||||||
BM_mesh_vert_coords_get(bm, xod->elem_array);
|
BM_mesh_vert_coords_get(
|
||||||
|
bm, MutableSpan(reinterpret_cast<float3 *>(xod->elem_array), elem_array_len));
|
||||||
xod_base = &xod->base;
|
xod_base = &xod->base;
|
||||||
|
|
||||||
if (key != nullptr) {
|
if (key != nullptr) {
|
||||||
|
|
|
@ -44,6 +44,9 @@
|
||||||
#include "ED_screen.hh"
|
#include "ED_screen.hh"
|
||||||
#include "ED_view3d.hh"
|
#include "ED_view3d.hh"
|
||||||
|
|
||||||
|
using blender::Array;
|
||||||
|
using blender::float3;
|
||||||
|
using blender::Span;
|
||||||
using blender::Vector;
|
using blender::Vector;
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
@ -236,17 +239,17 @@ static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int
|
||||||
}
|
}
|
||||||
|
|
||||||
if (best.ele) {
|
if (best.ele) {
|
||||||
const float(*coords)[3] = nullptr;
|
Span<float3> vert_positions;
|
||||||
{
|
{
|
||||||
Object *ob = gz_ele->bases[gz_ele->base_index]->object;
|
Object *ob = gz_ele->bases[gz_ele->base_index]->object;
|
||||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||||
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
|
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
|
||||||
Mesh *mesh_eval = BKE_object_get_editmesh_eval_cage(ob_eval);
|
Mesh *mesh_eval = BKE_object_get_editmesh_eval_cage(ob_eval);
|
||||||
if (BKE_mesh_wrapper_vert_len(mesh_eval) == bm->totvert) {
|
if (BKE_mesh_wrapper_vert_len(mesh_eval) == bm->totvert) {
|
||||||
coords = BKE_mesh_wrapper_vert_coords(mesh_eval);
|
vert_positions = BKE_mesh_wrapper_vert_coords(mesh_eval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EDBM_preselect_elem_update_from_single(gz_ele->psel, bm, best.ele, coords);
|
EDBM_preselect_elem_update_from_single(gz_ele->psel, bm, best.ele, vert_positions);
|
||||||
EDBM_preselect_elem_update_preview(gz_ele->psel, &vc, bm, best.ele, mval);
|
EDBM_preselect_elem_update_preview(gz_ele->psel, &vc, bm, best.ele, mval);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -406,13 +409,10 @@ static int gizmo_preselect_edgering_test_select(bContext *C, wmGizmo *gz, const
|
||||||
BMEditMesh *em_eval = BKE_editmesh_from_object(ob_eval);
|
BMEditMesh *em_eval = BKE_editmesh_from_object(ob_eval);
|
||||||
/* Re-allocate coords each update isn't ideal, however we can't be sure
|
/* Re-allocate coords each update isn't ideal, however we can't be sure
|
||||||
* the mesh hasn't been edited since last update. */
|
* the mesh hasn't been edited since last update. */
|
||||||
bool is_alloc = false;
|
Array<float3> storage;
|
||||||
const float(*coords)[3] = BKE_editmesh_vert_coords_when_deformed(
|
const Span<float3> vert_positions = BKE_editmesh_vert_coords_when_deformed(
|
||||||
vc.depsgraph, em_eval, scene_eval, ob_eval, nullptr, &is_alloc);
|
vc.depsgraph, em_eval, scene_eval, ob_eval, storage);
|
||||||
EDBM_preselect_edgering_update_from_edge(gz_ring->psel, bm, best.eed, 1, coords);
|
EDBM_preselect_edgering_update_from_edge(gz_ring->psel, bm, best.eed, 1, vert_positions);
|
||||||
if (is_alloc) {
|
|
||||||
MEM_freeN((void *)coords);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
EDBM_preselect_edgering_clear(gz_ring->psel);
|
EDBM_preselect_edgering_clear(gz_ring->psel);
|
||||||
|
|
|
@ -506,13 +506,11 @@ static void calc_deltas(CorrectiveSmoothModifierData *csmd,
|
||||||
Mesh *mesh,
|
Mesh *mesh,
|
||||||
const MDeformVert *dvert,
|
const MDeformVert *dvert,
|
||||||
const int defgrp_index,
|
const int defgrp_index,
|
||||||
const float (*rest_coords)[3],
|
const blender::Span<blender::float3> rest_coords)
|
||||||
uint verts_num)
|
|
||||||
{
|
{
|
||||||
const blender::Span<int> corner_verts = mesh->corner_verts();
|
const blender::Span<int> corner_verts = mesh->corner_verts();
|
||||||
|
|
||||||
blender::Array<blender::float3> smooth_vertex_coords(
|
blender::Array<blender::float3> smooth_vertex_coords(rest_coords);
|
||||||
blender::Span(reinterpret_cast<const blender::float3 *>(rest_coords), verts_num));
|
|
||||||
|
|
||||||
uint l_index;
|
uint l_index;
|
||||||
|
|
||||||
|
@ -644,43 +642,37 @@ static void correctivesmooth_modifier_do(ModifierData *md,
|
||||||
if (!csmd->delta_cache.deltas || (csmd->delta_cache.deltas_num != corner_verts.size()) ||
|
if (!csmd->delta_cache.deltas || (csmd->delta_cache.deltas_num != corner_verts.size()) ||
|
||||||
force_delta_cache_update)
|
force_delta_cache_update)
|
||||||
{
|
{
|
||||||
const float(*rest_coords)[3];
|
blender::Array<blender::float3> rest_coords_alloc;
|
||||||
bool is_rest_coords_alloc = false;
|
blender::Span<blender::float3> rest_coords;
|
||||||
|
|
||||||
store_cache_settings(csmd);
|
store_cache_settings(csmd);
|
||||||
|
|
||||||
if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
|
if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
|
||||||
/* caller needs to do sanity check here */
|
/* caller needs to do sanity check here */
|
||||||
csmd->bind_coords_num = uint(vertexCos.size());
|
csmd->bind_coords_num = uint(vertexCos.size());
|
||||||
rest_coords = csmd->bind_coords;
|
rest_coords = {reinterpret_cast<const blender::float3 *>(csmd->bind_coords),
|
||||||
|
csmd->bind_coords_num};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int me_numVerts;
|
|
||||||
if (em) {
|
if (em) {
|
||||||
rest_coords = BKE_editmesh_vert_coords_alloc_orco(em, &me_numVerts);
|
rest_coords_alloc = BKE_editmesh_vert_coords_alloc_orco(em);
|
||||||
is_rest_coords_alloc = true;
|
rest_coords = rest_coords_alloc;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const Mesh *object_mesh = static_cast<const Mesh *>(ob->data);
|
const Mesh *object_mesh = static_cast<const Mesh *>(ob->data);
|
||||||
rest_coords = reinterpret_cast<const float(*)[3]>(object_mesh->vert_positions().data());
|
rest_coords = object_mesh->vert_positions();
|
||||||
me_numVerts = object_mesh->verts_num;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BLI_assert(me_numVerts == int(vertexCos.size()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_TIME
|
#ifdef DEBUG_TIME
|
||||||
TIMEIT_START(corrective_smooth_deltas);
|
TIMEIT_START(corrective_smooth_deltas);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
calc_deltas(csmd, mesh, dvert, defgrp_index, rest_coords, uint(vertexCos.size()));
|
calc_deltas(csmd, mesh, dvert, defgrp_index, rest_coords);
|
||||||
|
|
||||||
#ifdef DEBUG_TIME
|
#ifdef DEBUG_TIME
|
||||||
TIMEIT_END(corrective_smooth_deltas);
|
TIMEIT_END(corrective_smooth_deltas);
|
||||||
#endif
|
#endif
|
||||||
if (is_rest_coords_alloc) {
|
|
||||||
MEM_freeN((void *)rest_coords);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
|
if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
|
||||||
|
|
Loading…
Reference in New Issue