[Bf-blender-cvs] [44d67b6dc8b] master: Transform: Add option to exclude back facing geometry from snapping
mano-wii
noreply at git.blender.org
Thu Oct 31 18:10:02 CET 2019
Commit: 44d67b6dc8b973dd924ef8b8d1177d650f559790
Author: mano-wii
Date: Thu Oct 31 14:09:53 2019 -0300
Branches: master
https://developer.blender.org/rB44d67b6dc8b973dd924ef8b8d1177d650f559790
Transform: Add option to exclude back facing geometry from snapping
Add new `Backface Culling` option to the snapping properties.
This option has nothing to do with the view3d display or the
workbench `Backface Culling` option.
Limitation:
- In edit mode, this option only affects snap to faces.
Maniphest Tasks: T71217
Differential Revision: https://developer.blender.org/D6155
===================================================================
M release/scripts/startup/bl_ui/space_view3d.py
M source/blender/editors/include/ED_transform_snap_object_context.h
M source/blender/editors/transform/transform_snap.c
M source/blender/editors/transform/transform_snap_object.c
M source/blender/makesdna/DNA_scene_types.h
M source/blender/makesrna/intern/rna_scene.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index ac1243561a3..8ff0ba7bce4 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -6082,6 +6082,8 @@ class VIEW3D_PT_snapping(Panel):
row = col.row(align=True)
row.prop(tool_settings, "snap_target", expand=True)
+ col.prop(tool_settings, "use_snap_backface_culling")
+
if obj:
if object_mode == 'EDIT':
col.prop(tool_settings, "use_snap_self")
diff --git a/source/blender/editors/include/ED_transform_snap_object_context.h b/source/blender/editors/include/ED_transform_snap_object_context.h
index 40e0005b487..0e20abe4221 100644
--- a/source/blender/editors/include/ED_transform_snap_object_context.h
+++ b/source/blender/editors/include/ED_transform_snap_object_context.h
@@ -68,6 +68,8 @@ struct SnapObjectParams {
unsigned int use_object_edit_cage : 1;
/* snap to the closest element, use when using more than one snap type */
unsigned int use_occlusion_test : 1;
+ /* exclude back facing geometry from snapping */
+ unsigned int use_backface_culling : 1;
};
typedef struct SnapObjectContext SnapObjectContext;
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index a66e76abc58..15208c1a7d2 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -379,6 +379,8 @@ void applyProject(TransInfo *t)
.snap_select = t->tsnap.modeSelect,
.use_object_edit_cage = (t->flag & T_EDIT) != 0,
.use_occlusion_test = false,
+ .use_backface_culling = (t->scene->toolsettings->snap_flag &
+ SCE_SNAP_BACKFACE_CULLING) != 0,
},
mval_fl,
NULL,
@@ -1364,6 +1366,8 @@ short snapObjectsTransform(
.snap_select = t->tsnap.modeSelect,
.use_object_edit_cage = (t->flag & T_EDIT) != 0,
.use_occlusion_test = t->scene->toolsettings->snap_mode != SCE_SNAP_MODE_FACE,
+ .use_backface_culling = (t->scene->toolsettings->snap_flag &
+ SCE_SNAP_BACKFACE_CULLING) != 0,
},
mval,
t->tsnap.snapTarget,
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index f35a2808f22..14e8b8f97e0 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -201,8 +201,12 @@ static SnapObjectData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext
return *sod_p;
}
-typedef void (*IterSnapObjsCallback)(
- SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data);
+typedef void (*IterSnapObjsCallback)(SnapObjectContext *sctx,
+ bool is_obedit,
+ bool use_backface_culling,
+ Object *ob,
+ float obmat[4][4],
+ void *data);
/**
* Walks through all objects in the scene to create the list of objects to snap.
@@ -219,6 +223,7 @@ static void iter_snap_objects(SnapObjectContext *sctx,
const View3D *v3d = sctx->v3d_data.v3d;
const eSnapSelect snap_select = params->snap_select;
const bool use_object_edit_cage = params->use_object_edit_cage;
+ const bool use_backface_culling = params->use_backface_culling;
Base *base_act = view_layer->basact;
for (Base *base = view_layer->object_bases.first; base != NULL; base = base->next) {
@@ -250,12 +255,14 @@ static void iter_snap_objects(SnapObjectContext *sctx,
DupliObject *dupli_ob;
ListBase *lb = object_duplilist(sctx->depsgraph, sctx->scene, obj_eval);
for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) {
- sob_callback(sctx, use_object_edit_cage, dupli_ob->ob, dupli_ob->mat, data);
+ sob_callback(
+ sctx, use_object_edit_cage, use_backface_culling, dupli_ob->ob, dupli_ob->mat, data);
}
free_object_duplilist(lb);
}
- sob_callback(sctx, use_object_edit_cage, obj_eval, obj_eval->obmat, data);
+ sob_callback(
+ sctx, use_object_edit_cage, use_backface_culling, obj_eval, obj_eval->obmat, data);
}
}
@@ -350,6 +357,70 @@ static void raycast_all_cb(void *userdata, int index, const BVHTreeRay *ray, BVH
}
}
+static bool raycast_tri_backface_culling_test(
+ const float dir[3], const float v0[3], const float v1[3], const float v2[3], float no[3])
+{
+ cross_tri_v3(no, v0, v1, v2);
+ return dot_v3v3(no, dir) < 0.0f;
+}
+
+/* Callback to raycast with backface culling (Mesh). */
+static void mesh_looptri_raycast_backface_culling_cb(void *userdata,
+ int index,
+ const BVHTreeRay *ray,
+ BVHTreeRayHit *hit)
+{
+ const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata;
+ const MVert *vert = data->vert;
+ const MLoopTri *lt = &data->looptri[index];
+ const float *vtri_co[3] = {
+ vert[data->loop[lt->tri[0]].v].co,
+ vert[data->loop[lt->tri[1]].v].co,
+ vert[data->loop[lt->tri[2]].v].co,
+ };
+ float dist = bvhtree_ray_tri_intersection(ray, hit->dist, UNPACK3(vtri_co));
+
+ if (dist >= 0 && dist < hit->dist) {
+ float no[3];
+ if (raycast_tri_backface_culling_test(ray->direction, UNPACK3(vtri_co), no)) {
+ hit->index = index;
+ hit->dist = dist;
+ madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, dist);
+ normalize_v3_v3(hit->no, no);
+ }
+ }
+}
+
+/* Callback to raycast with backface culling (EditMesh). */
+static void editmesh_looptri_raycast_backface_culling_cb(void *userdata,
+ int index,
+ const BVHTreeRay *ray,
+ BVHTreeRayHit *hit)
+{
+ const BVHTreeFromEditMesh *data = (BVHTreeFromEditMesh *)userdata;
+ BMEditMesh *em = data->em;
+ const BMLoop **ltri = (const BMLoop **)em->looptris[index];
+
+ const float *t0, *t1, *t2;
+ t0 = ltri[0]->v->co;
+ t1 = ltri[1]->v->co;
+ t2 = ltri[2]->v->co;
+
+ {
+ float dist = bvhtree_ray_tri_intersection(ray, hit->dist, t0, t1, t2);
+
+ if (dist >= 0 && dist < hit->dist) {
+ float no[3];
+ if (raycast_tri_backface_culling_test(ray->direction, t0, t1, t2, no)) {
+ hit->index = index;
+ hit->dist = dist;
+ madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, dist);
+ normalize_v3_v3(hit->no, no);
+ }
+ }
+ }
+}
+
static bool raycastMesh(SnapObjectContext *sctx,
const float ray_start[3],
const float ray_dir[3],
@@ -358,6 +429,7 @@ static bool raycastMesh(SnapObjectContext *sctx,
const float obmat[4][4],
const unsigned int ob_index,
bool use_hide,
+ bool use_backface_culling,
/* read/write args */
float *ray_depth,
/* return args */
@@ -494,7 +566,8 @@ static bool raycastMesh(SnapObjectContext *sctx,
ray_normal_local,
0.0f,
&hit,
- treedata->raycast_callback,
+ use_backface_culling ? mesh_looptri_raycast_backface_culling_cb :
+ treedata->raycast_callback,
treedata) != -1) {
hit.dist += len_diff;
hit.dist /= local_scale;
@@ -530,6 +603,7 @@ static bool raycastEditMesh(SnapObjectContext *sctx,
BMEditMesh *em,
const float obmat[4][4],
const unsigned int ob_index,
+ bool use_backface_culling,
/* read/write args */
float *ray_depth,
/* return args */
@@ -670,7 +744,8 @@ static bool raycastEditMesh(SnapObjectContext *sctx,
ray_normal_local,
0.0f,
&hit,
- treedata->raycast_callback,
+ use_backface_culling ? editmesh_looptri_raycast_backface_culling_cb :
+ treedata->raycast_callback,
treedata) != -1) {
hit.dist += len_diff;
hit.dist /= local_scale;
@@ -715,6 +790,7 @@ static bool raycastObj(SnapObjectContext *sctx,
const unsigned int ob_index,
bool use_obedit,
bool use_occlusion_test,
+ bool use_backface_culling,
/* read/write args */
float *ray_depth,
/* return args */
@@ -753,6 +829,7 @@ static bool raycastObj(SnapObjectContext *sctx,
em,
obmat,
ob_index,
+ use_backface_culling,
ray_depth,
r_loc,
r_no,
@@ -773,6 +850,7 @@ static bool raycastObj(SnapObjectContext *sctx,
obmat,
ob_index,
use_hide,
+ use_backface_culling,
ray_depth,
r_loc,
r_no,
@@ -792,6 +870,7 @@ static bool ra
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list