Mesh: Avoid calculating normals when building BVH tree
Though they are sometimes used by users of the BVH tree, mostly vertex normals when building the BVH tree is unnecessary. Skip it instead and avoid storing the vertex normals in the BVH tree cache. They are just calculated in the few places they are actually needed. This should save at least a few percent of the runtime in some cases where the normals weren't needed otherwise.
This commit is contained in:
parent
cc12d2a5a0
commit
276d7f7c19
|
@ -60,7 +60,6 @@ typedef struct BVHTreeFromMesh {
|
|||
|
||||
/* Vertex array, so that callbacks have instant access to data. */
|
||||
const struct MVert *vert;
|
||||
const float (*vert_normals)[3];
|
||||
const struct MEdge *edge;
|
||||
const struct MFace *face;
|
||||
const struct MLoop *loop;
|
||||
|
|
|
@ -74,6 +74,7 @@ typedef struct ShrinkwrapTreeData {
|
|||
BVHTreeFromMesh treeData;
|
||||
|
||||
const struct MPoly *polys;
|
||||
const float (*vert_normals)[3];
|
||||
const float (*pnors)[3];
|
||||
const float (*clnors)[3];
|
||||
ShrinkwrapBoundaryData *boundary;
|
||||
|
|
|
@ -578,7 +578,6 @@ static void bvhtree_from_mesh_setup_data(BVHTree *tree,
|
|||
const MFace *face,
|
||||
const MLoop *loop,
|
||||
const MLoopTri *looptri,
|
||||
const float (*vert_normals)[3],
|
||||
BVHTreeFromMesh *r_data)
|
||||
{
|
||||
memset(r_data, 0, sizeof(*r_data));
|
||||
|
@ -590,7 +589,6 @@ static void bvhtree_from_mesh_setup_data(BVHTree *tree,
|
|||
r_data->face = face;
|
||||
r_data->loop = loop;
|
||||
r_data->looptri = looptri;
|
||||
r_data->vert_normals = vert_normals;
|
||||
|
||||
switch (bvh_cache_type) {
|
||||
case BVHTREE_FROM_VERTS:
|
||||
|
@ -778,7 +776,7 @@ BVHTree *bvhtree_from_mesh_verts_ex(BVHTreeFromMesh *data,
|
|||
if (data) {
|
||||
/* Setup BVHTreeFromMesh */
|
||||
bvhtree_from_mesh_setup_data(
|
||||
tree, BVHTREE_FROM_VERTS, vert, nullptr, nullptr, nullptr, nullptr, nullptr, data);
|
||||
tree, BVHTREE_FROM_VERTS, vert, nullptr, nullptr, nullptr, nullptr, data);
|
||||
}
|
||||
|
||||
return tree;
|
||||
|
@ -913,7 +911,7 @@ BVHTree *bvhtree_from_mesh_edges_ex(BVHTreeFromMesh *data,
|
|||
if (data) {
|
||||
/* Setup BVHTreeFromMesh */
|
||||
bvhtree_from_mesh_setup_data(
|
||||
tree, BVHTREE_FROM_EDGES, vert, edge, nullptr, nullptr, nullptr, nullptr, data);
|
||||
tree, BVHTREE_FROM_EDGES, vert, edge, nullptr, nullptr, nullptr, data);
|
||||
}
|
||||
|
||||
return tree;
|
||||
|
@ -1130,7 +1128,7 @@ BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data,
|
|||
if (data) {
|
||||
/* Setup BVHTreeFromMesh */
|
||||
bvhtree_from_mesh_setup_data(
|
||||
tree, BVHTREE_FROM_LOOPTRI, vert, nullptr, nullptr, mloop, looptri, nullptr, data);
|
||||
tree, BVHTREE_FROM_LOOPTRI, vert, nullptr, nullptr, mloop, looptri, data);
|
||||
}
|
||||
|
||||
return tree;
|
||||
|
@ -1233,16 +1231,17 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
|
|||
const Span<MLoop> loops = mesh->loops();
|
||||
|
||||
/* Setup BVHTreeFromMesh */
|
||||
bvhtree_from_mesh_setup_data(nullptr,
|
||||
bvh_cache_type,
|
||||
verts.data(),
|
||||
edges.data(),
|
||||
(const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE),
|
||||
loops.data(),
|
||||
looptri,
|
||||
BKE_mesh_vertex_normals_ensure(mesh),
|
||||
data);
|
||||
|
||||
{
|
||||
SCOPED_TIMER_AVERAGED(__func__);
|
||||
bvhtree_from_mesh_setup_data(nullptr,
|
||||
bvh_cache_type,
|
||||
verts.data(),
|
||||
edges.data(),
|
||||
(const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE),
|
||||
loops.data(),
|
||||
looptri,
|
||||
data);
|
||||
}
|
||||
bool lock_started = false;
|
||||
data->cached = bvhcache_find(
|
||||
bvh_cache_p, bvh_cache_type, &data->tree, &lock_started, &mesh->runtime->eval_mutex);
|
||||
|
|
|
@ -1377,6 +1377,7 @@ BLI_INLINE bool cloth_bend_set_poly_vert_array(int **poly, int len, const MLoop
|
|||
}
|
||||
|
||||
static bool find_internal_spring_target_vertex(BVHTreeFromMesh *treedata,
|
||||
const float (*vert_normals)[3],
|
||||
uint v_idx,
|
||||
RNG *rng,
|
||||
float max_length,
|
||||
|
@ -1388,7 +1389,7 @@ static bool find_internal_spring_target_vertex(BVHTreeFromMesh *treedata,
|
|||
float radius;
|
||||
|
||||
copy_v3_v3(co, treedata->vert[v_idx].co);
|
||||
negate_v3_v3(no, treedata->vert_normals[v_idx]);
|
||||
negate_v3_v3(no, vert_normals[v_idx]);
|
||||
|
||||
float vec_len = sin(max_diversion);
|
||||
float offset[3];
|
||||
|
@ -1518,9 +1519,12 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
|
|||
BKE_bvhtree_from_mesh_get(&treedata, tmp_mesh ? tmp_mesh : mesh, BVHTREE_FROM_LOOPTRI, 2);
|
||||
rng = BLI_rng_new_srandom(0);
|
||||
|
||||
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(tmp_mesh ? tmp_mesh : mesh);
|
||||
|
||||
for (int i = 0; i < mvert_num; i++) {
|
||||
if (find_internal_spring_target_vertex(
|
||||
&treedata,
|
||||
vert_normals,
|
||||
i,
|
||||
rng,
|
||||
clmd->sim_parms->internal_spring_max_length,
|
||||
|
|
|
@ -115,6 +115,7 @@ bool BKE_shrinkwrap_init_tree(
|
|||
|
||||
data->mesh = mesh;
|
||||
data->polys = BKE_mesh_polys(mesh);
|
||||
data->vert_normals = BKE_mesh_vertex_normals_ensure(mesh);
|
||||
|
||||
if (shrinkType == MOD_SHRINKWRAP_NEAREST_VERTEX) {
|
||||
data->bvh = BKE_bvhtree_from_mesh_get(&data->treeData, mesh, BVHTREE_FROM_VERTS, 2);
|
||||
|
@ -993,8 +994,8 @@ static void target_project_edge(const ShrinkwrapTreeData *tree,
|
|||
CLAMP(x, 0, 1);
|
||||
|
||||
float vedge_no[2][3];
|
||||
copy_v3_v3(vedge_no[0], data->vert_normals[edge->v1]);
|
||||
copy_v3_v3(vedge_no[1], data->vert_normals[edge->v2]);
|
||||
copy_v3_v3(vedge_no[0], tree->vert_normals[edge->v1]);
|
||||
copy_v3_v3(vedge_no[1], tree->vert_normals[edge->v2]);
|
||||
|
||||
interp_v3_v3v3(hit_co, vedge_co[0], vedge_co[1], x);
|
||||
interp_v3_v3v3(hit_no, vedge_no[0], vedge_no[1], x);
|
||||
|
@ -1040,9 +1041,9 @@ static void mesh_looptri_target_project(void *userdata,
|
|||
}
|
||||
|
||||
/* Decode normals */
|
||||
copy_v3_v3(vtri_no[0], tree->treeData.vert_normals[loop[0]->v]);
|
||||
copy_v3_v3(vtri_no[1], tree->treeData.vert_normals[loop[1]->v]);
|
||||
copy_v3_v3(vtri_no[2], tree->treeData.vert_normals[loop[2]->v]);
|
||||
copy_v3_v3(vtri_no[0], tree->vert_normals[loop[0]->v]);
|
||||
copy_v3_v3(vtri_no[1], tree->vert_normals[loop[1]->v]);
|
||||
copy_v3_v3(vtri_no[2], tree->vert_normals[loop[2]->v]);
|
||||
|
||||
/* Solve the equations for the triangle */
|
||||
if (target_project_solve_point_tri(vtri_co, vtri_no, co, raw_hit_co, dist_sq, hit_co, hit_no)) {
|
||||
|
@ -1176,7 +1177,7 @@ void BKE_shrinkwrap_compute_smooth_normal(const ShrinkwrapTreeData *tree,
|
|||
{
|
||||
const BVHTreeFromMesh *treeData = &tree->treeData;
|
||||
const MLoopTri *tri = &treeData->looptri[looptri_idx];
|
||||
const float(*vert_normals)[3] = tree->treeData.vert_normals;
|
||||
const float(*vert_normals)[3] = tree->vert_normals;
|
||||
|
||||
/* Interpolate smooth normals if enabled. */
|
||||
if ((tree->polys[tri->poly].flag & ME_SMOOTH) != 0) {
|
||||
|
|
|
@ -255,7 +255,6 @@ static void snap_object_data_mesh_get(SnapObjectContext *sctx,
|
|||
r_treedata, me_eval, use_hide ? BVHTREE_FROM_LOOPTRI_NO_HIDDEN : BVHTREE_FROM_LOOPTRI, 4);
|
||||
|
||||
BLI_assert(r_treedata->vert == verts.data());
|
||||
BLI_assert(!verts.data() || r_treedata->vert_normals);
|
||||
BLI_assert(r_treedata->loop == loops.data());
|
||||
BLI_assert(!polys.data() || r_treedata->looptri);
|
||||
BLI_assert(!r_treedata->tree || r_treedata->looptri);
|
||||
|
|
Loading…
Reference in New Issue