[Bf-blender-cvs] [55389d4899d] blender2.8: Transform: Make snapDerivedMesh use bvhtrees from loose edges and bvhtrees from loose verts.
Germano
noreply at git.blender.org
Thu May 10 18:49:44 CEST 2018
Commit: 55389d4899d4ebea090dbd9579179455d04900b7
Author: Germano
Date: Thu May 10 13:40:30 2018 -0300
Branches: blender2.8
https://developer.blender.org/rB55389d4899d4ebea090dbd9579179455d04900b7
Transform: Make snapDerivedMesh use bvhtrees from loose edges and bvhtrees from loose verts.
Bvhtrees take up a lot of memory space, reusing the common bvhtree of looptris to snap to vertices and edges is a good way to save memory.
Unfortunately we have a worsening performance in the snapping operation around 63% (addition to the original time).
But as we often do not need to build a bvhtree of loose verts and loose edges, we have an improvement in cache time :)
Since the CPU time of snapping operations (no matter how higth poly the object is) corresponds to less than 0.01% of all CPU time of a blender frame, that change is not really significant.
Snapping operations on a mesh in edit mode have not changed significantly.
Signed-off-by: Germano <germano.costa at ig.com.br>
===================================================================
M source/blender/editors/transform/transform_snap_object.c
===================================================================
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index 9334268b622..8a336f3b5b4 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -96,7 +96,12 @@ typedef struct SnapObjectData {
typedef struct SnapObjectData_Mesh {
SnapObjectData sd;
- BVHTreeFromMesh *bvh_trees[3];
+ BVHTreeFromMesh treedata;
+ BVHTree *bvhtree[2]; /* from loose verts and from loose edges */
+ uint has_looptris : 1;
+ uint has_loose_edge : 1;
+ uint has_loose_vert : 1;
+
} SnapObjectData_Mesh;
typedef struct SnapObjectData_EditMesh {
@@ -397,7 +402,6 @@ static bool raycastMesh(
}
SnapObjectData_Mesh *sod = NULL;
- BVHTreeFromMesh *treedata;
void **sod_p;
if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
@@ -408,43 +412,35 @@ static bool raycastMesh(
sod->sd.type = SNAP_MESH;
}
- if (sod->bvh_trees[2] == NULL) {
- sod->bvh_trees[2] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*treedata));
- }
+ BVHTreeFromMesh *treedata = &sod->treedata;
- treedata = sod->bvh_trees[2];
-
- if (treedata) {
- /* the tree is owned by the DM and may have been freed since we last used! */
- if (treedata->tree) {
- if (treedata->cached && !bvhcache_has_tree(me->runtime.bvh_cache, treedata->tree)) {
- free_bvhtree_from_mesh(treedata);
+ /* The tree is owned by the DM and may have been freed since we last used. */
+ if (treedata->tree) {
+ BLI_assert(treedata->cached);
+ if (!bvhcache_has_tree(me->runtime.bvh_cache, treedata->tree)) {
+ free_bvhtree_from_mesh(treedata);
+ }
+ else {
+ /* Update Pointers. */
+ if (treedata->vert && treedata->vert_allocated == false) {
+ treedata->vert = me->mvert;
}
- else {
- /* Update Pointers. */
- if (treedata->vert && treedata->vert_allocated == false) {
- treedata->vert = me->mvert;
- }
- if (treedata->loop && treedata->loop_allocated == false) {
- treedata->loop = me->mloop;
- }
- if (treedata->looptri && treedata->looptri_allocated == false) {
- treedata->looptri = BKE_mesh_runtime_looptri_ensure(me);
- }
+ if (treedata->loop && treedata->loop_allocated == false) {
+ treedata->loop = me->mloop;
+ }
+ if (treedata->looptri && treedata->looptri_allocated == false) {
+ treedata->looptri = BKE_mesh_runtime_looptri_ensure(me);
}
}
+ }
- if (treedata->tree == NULL) {
- BKE_bvhtree_from_mesh_get(treedata, me, BVHTREE_FROM_LOOPTRI, 4);
+ if (treedata->tree == NULL) {
+ BKE_bvhtree_from_mesh_get(treedata, me, BVHTREE_FROM_LOOPTRI, 4);
- if (treedata->tree == NULL) {
- return retval;
- }
+ if (treedata->tree == NULL) {
+ return retval;
}
}
- else {
- return retval;
- }
/* Only use closer ray_start in case of ortho view! In perspective one, ray_start may already
* been *inside* boundbox, leading to snap failures (see T38409).
@@ -820,35 +816,84 @@ static bool raycastObjects(
/** Snap Nearest utilities
* \{ */
-static void copy_dm_vert_no(const int index, float r_no[3], const BVHTreeFromMesh *data)
+static void cb_mvert_co_get(
+ const int index, const float **co, const BVHTreeFromMesh *data)
+{
+ *co = data->vert[index].co;
+}
+
+static void cb_bvert_co_get(
+ const int index, const float **co, const BMEditMesh *data)
+{
+ BMVert *eve = BM_vert_at_index(data->bm, index);
+ *co = eve->co;
+}
+
+static void cb_mvert_no_copy(
+ const int index, float r_no[3], const BVHTreeFromMesh *data)
{
const MVert *vert = data->vert + index;
normal_short_to_float_v3(r_no, vert->no);
}
-static void copy_bvert_no(const int index, float r_no[3], const BVHTreeFromEditMesh *data)
+static void cb_bvert_no_copy(
+ const int index, float r_no[3], const BMEditMesh *data)
{
- BMVert *eve = BM_vert_at_index(data->em->bm, index);
+ BMVert *eve = BM_vert_at_index(data->bm, index);
copy_v3_v3(r_no, eve->no);
}
-static void get_dm_edge_verts(const int index, const float *v_pair[2], const BVHTreeFromMesh *data)
+static void cb_medge_verts_get(
+ const int index, int v_index[2], const BVHTreeFromMesh *data)
{
const MVert *vert = data->vert;
- const MEdge *edge = data->edge + index;
+ const MEdge *edge = &data->edge[index];
+
+ v_index[0] = edge->v1;
+ v_index[1] = edge->v2;
+
+}
+
+static void cb_bedge_verts_get(
+ const int index, int v_index[2], const BMEditMesh *data)
+{
+ BMEdge *eed = BM_edge_at_index(data->bm, index);
- v_pair[0] = vert[edge->v1].co;
- v_pair[1] = vert[edge->v2].co;
+ v_index[0] = BM_elem_index_get(eed->v1);
+ v_index[1] = BM_elem_index_get(eed->v2);
}
-static void get_bedge_verts(const int index, const float *v_pair[2], const BVHTreeFromEditMesh *data)
+static void cb_mlooptri_edges_get(
+ const int index, int v_index[3], const BVHTreeFromMesh *data)
{
- BMEdge *eed = BM_edge_at_index(data->em->bm, index);
+ const MEdge *medge = data->edge;
+ const MLoop *mloop = data->loop;
+ const MLoopTri *lt = &data->looptri[index];
+ for (int j = 2, j_next = 0; j_next < 3; j = j_next++) {
+ const MEdge *ed = &medge[mloop[lt->tri[j]].e];
+ unsigned int tri_edge[2] = {mloop[lt->tri[j]].v, mloop[lt->tri[j_next]].v};
+ if (ELEM(ed->v1, tri_edge[0], tri_edge[1]) &&
+ ELEM(ed->v2, tri_edge[0], tri_edge[1]))
+ {
+ //printf("real edge found\n");
+ v_index[j] = mloop[lt->tri[j]].e;
+ }
+ else
+ v_index[j] = -1;
+ }
+}
- v_pair[0] = eed->v1->co;
- v_pair[1] = eed->v2->co;
+static void cb_mlooptri_verts_get(
+ const int index, int v_index[3], const BVHTreeFromMesh *data)
+{
+ const MLoop *loop = data->loop;
+ const MLoopTri *looptri = &data->looptri[index];
+
+ v_index[0] = loop[looptri->tri[0]].v;
+ v_index[1] = loop[looptri->tri[1]].v;
+ v_index[2] = loop[looptri->tri[2]].v;
}
static bool test_projected_vert_dist(
@@ -1130,7 +1175,10 @@ static float dist_squared_to_projected_aabb_simple(
/** Walk DFS
* \{ */
-typedef void (*Nearest2DGetEdgeVertsCallback)(const int index, const float *v_pair[2], void *data);
+typedef void (*Nearest2DGetVertCoCallback)(const int index, const float **co, void *data);
+typedef void (*Nearest2DGetEdgeVertsCallback)(const int index, int v_index[2], void *data);
+typedef void (*Nearest2DGetTriVertsCallback)(const int index, int v_index[3], void *data);
+typedef void (*Nearest2DGetTriEdgesCallback)(const int index, int e_index[3], void *data); /* Equal the previous one */
typedef void (*Nearest2DCopyVertNoCallback)(const int index, float r_no[3], void *data);
typedef struct Nearest2dUserData {
@@ -1143,9 +1191,14 @@ typedef struct Nearest2dUserData {
float depth_range[2];
void *userdata;
- Nearest2DGetEdgeVertsCallback get_edge_verts;
+ Nearest2DGetVertCoCallback get_vert_co;
+ Nearest2DGetEdgeVertsCallback get_edge_verts_index;
+ Nearest2DGetTriVertsCallback get_tri_verts_index;
+ Nearest2DGetTriEdgesCallback get_tri_edges_index;
Nearest2DCopyVertNoCallback copy_vert_no;
+ short snap_to;
+
int index;
float co[3];
float no[3];
@@ -1162,15 +1215,21 @@ static bool cb_walk_parent_snap_project(const BVHTreeAxisRange *bounds, void *us
return rdist < data->dist_px_sq;
}
-static bool cb_walk_leaf_snap_vert(const BVHTreeAxisRange *bounds, int index, void *userdata)
+static bool cb_nearest_walk_order(
+ const BVHTreeAxisRange *UNUSED(bounds), char axis, void *userdata)
+{
+ const bool *r_axis_closest = ((struct Nearest2dUserData *)userdata)->r_axis_closest;
+ return r_axis_closest[axis];
+}
+
+static bool cb_walk_leaf_snap_vert(
+ const BVHTreeAxisRange *UNUSED(bounds), int index, void *userdata)
{
struct Nearest2dUserData *data = userdata;
struct Nearest2dPrecalc *neasrest_precalc = &data->data_precalc;
- const float co[3] = {
- (bounds[0].min + bounds[0].max) / 2,
- (bounds[1].min + bounds[1].max) / 2,
- (bounds[2].min + bounds[2].max) / 2,
- };
+
+ float *co;
+ data->get_vert_co(index, &co, data->userdata);
if (test_projected_vert_dist(
data->depth_range,
@@ -1187,36 +1246,77 @@ static bool cb_walk_leaf_snap_vert(const BVHTreeAxisRange *bounds, int index, vo
return true;
}
-static bool cb_walk_leaf_snap_edge(const BVHTreeAxisRange *UNUSED(bounds), int index, void *userdata)
+static bool cb_walk_leaf_snap_edge(
+ const BVHTreeAxisRange *UNUSED(bounds), int index, void *userdata)
{
struct Nearest2dUserData *data = userdata;
struct Nearest2dPrecalc *neasrest_precalc = &data->data_precalc;
- const float *v_pair[2];
- data->get_edge_verts(index, v_pair, data->userdata);
-
- if (test_projected_edge_dist(
- data->depth_range,
- neasrest_precalc->mval,
- neasrest_precalc->pmat,
- neasrest_precalc->win_half,
- neasrest_precalc->is_persp,
- neasrest_precalc->ray_origin_local,
- neasrest_precalc->ray_direction_local,
- v_pair[0], v_pair[1],
- &data->dist_px_sq,
- data->co))
- {
- sub_v3_v3v3(data->no, v_pair[0], v_pair[1]);
- data->index = index;
+ int vindex[2];
+ data->get_edge_verts_index(index, vindex, data->userdata);
+
+ if (data->snap_to == SCE_SNAP_MODE_EDGE) {
+ bool vert_snapped = false;
+ const float *v_pair[2];
+ data->get_vert_co(vindex[0], &v_pair[0], data->userdata);
+ data->get_vert_co(vindex[1], &v_pair[1], data->userdata);
+
+ if (test_projected_edge_dist(
+ data->depth_range,
+ neasrest_precalc->mval,
+ neasrest_precalc->pmat,
+ neasrest_precalc->win_half,
+ neasrest_precalc->is_persp,
+ neasrest_precalc->ray_origin_local,
+ neasrest_precalc->ray_direction_local,
+ v_pair[0], v_pair[1],
+ &data->dist_px_sq,
+ data->co))
+ {
+ sub_v3_v3v3(data->no, v_pair[0], v_pair[1]);
+ data->index = index;
+ }
+ }
+ else {
+ for (int i = 0; i < 2; i++) {
+ if (vindex[i] == data->index) {
+ continue;
+ }
+ cb_walk_leaf_snap_vert(NULL, vindex[i], userdata);
+ }
}
+
return true;
}
-static bool cb_nearest_walk_order(const BVHTreeAxisRange *UNUSED(bounds), char axis, void *userdata)
+static bool cb_walk_leaf_snap_tri(
+ const BVHTreeAxisRange *UNUSED(bounds), int index, void *
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list