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. @@ _______________________________________________ Bf-blender-cvs mailing list [email protected] https://lists.blender.org/mailman/listinfo/bf-blender-cvs
