[Bf-blender-cvs] [812af65c621] blender2.8-snapping_with_occlusion: Transform: snap_object: Make snapDerivedMesh use bvhtrees from loose edges and bvhtrees from loose verts.
Germano
noreply at git.blender.org
Mon May 7 01:09:04 CEST 2018
Commit: 812af65c621af633303a9101c57d2d26886e2007
Author: Germano
Date: Sun May 6 20:08:05 2018 -0300
Branches: blender2.8-snapping_with_occlusion
https://developer.blender.org/rB812af65c621af633303a9101c57d2d26886e2007
Transform: snap_object: 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 worse performance: worsening around 63% in the snap operation and 46% in the creation of bvhtrees.
But 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.
===================================================================
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 40b71410014..7a96f2be307 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -94,9 +94,11 @@ typedef struct SnapObjectData {
typedef struct SnapObjectData_Mesh {
SnapObjectData sd;
- BVHTreeFromMesh *bvh_trees[3];
- MPoly *mpoly;
- bool poly_allocated;
+ BVHTreeFromMesh treedata;
+ BVHTree *bvhtree[2]; /* from loose verts and from loose edges */
+ int has_looptris : 1;
+ int has_loose_edge : 1;
+ int has_loose_vert : 1;
} SnapObjectData_Mesh;
@@ -409,7 +411,6 @@ static bool raycastDerivedMesh(
}
SnapObjectData_Mesh *sod = NULL;
- BVHTreeFromMesh *treedata;
void **sod_p;
if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
@@ -420,46 +421,35 @@ static bool raycastDerivedMesh(
sod->sd.type = SNAP_MESH;
}
- if (sod->bvh_trees[2] == NULL) {
- sod->bvh_trees[2] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*treedata));
- }
-
- treedata = sod->bvh_trees[2];
+ BVHTreeFromMesh *treedata = &sod->treedata;
- 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(dm->bvhCache, 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(dm->bvhCache, treedata->tree)) {
+ free_bvhtree_from_mesh(treedata);
+ }
+ else {
+ /* Update pointers. */
+ if (treedata->vert_allocated == false) {
+ treedata->vert = DM_get_vert_array(dm, &treedata->vert_allocated);
}
- else {
- if (treedata->vert == NULL) {
- treedata->vert = DM_get_vert_array(dm, &treedata->vert_allocated);
- }
- if (treedata->loop == NULL) {
- treedata->loop = DM_get_loop_array(dm, &treedata->loop_allocated);
- }
- if (treedata->looptri == NULL) {
- if (sod->mpoly == NULL) {
- sod->mpoly = DM_get_poly_array(dm, &sod->poly_allocated);
- }
- treedata->looptri = dm->getLoopTriArray(dm);
- treedata->looptri_allocated = false;
- }
+ if (treedata->loop_allocated == false) {
+ treedata->loop = DM_get_loop_array(dm, &treedata->loop_allocated);
+ }
+ if (treedata->looptri_allocated == false) {
+ treedata->looptri = dm->getLoopTriArray(dm);
}
}
+ }
- if (treedata->tree == NULL) {
- bvhtree_from_mesh_get(treedata, dm, BVHTREE_FROM_LOOPTRI, 4);
+ if (treedata->tree == NULL) {
+ bvhtree_from_mesh_get(treedata, dm, 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).
@@ -852,35 +842,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_index[0] = BM_elem_index_get(eed->v1);
+ v_index[1] = BM_elem_index_get(eed->v2);
+}
- v_pair[0] = vert[edge->v1].co;
- v_pair[1] = vert[edge->v2].co;
+static void cb_mlooptri_edges_get(
+ const int index, int v_index[3], const BVHTreeFromMesh *data)
+{
+ 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;
+ }
}
-static void get_bedge_verts(const int index, const float *v_pair[2], const BVHTreeFromEditMesh *data)
+static void cb_mlooptri_verts_get(
+ const int index, int v_index[3], const BVHTreeFromMesh *data)
{
- BMEdge *eed = BM_edge_at_index(data->em->bm, index);
+ const MLoop *loop = data->loop;
+ const MLoopTri *looptri = &data->looptri[index];
- v_pair[0] = eed->v1->co;
- v_pair[1] = eed->v2->co;
+ 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(
@@ -1162,7 +1201,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 {
@@ -1175,9 +1217,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];
@@ -1194,15 +1241,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,
@@ -1219,36 +1272,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
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list