diff options
Diffstat (limited to 'source/blender/editors/transform/transform_snap_object.c')
-rw-r--r-- | source/blender/editors/transform/transform_snap_object.c | 330 |
1 files changed, 132 insertions, 198 deletions
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index 2cfeedbb346..f2cdeacb13d 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -110,7 +110,6 @@ typedef struct SnapObjectData { } SnapObjectData; struct SnapObjectContext { - Main *bmain; Scene *scene; int flag; @@ -145,6 +144,17 @@ struct SnapObjectContext { /** \} */ /* -------------------------------------------------------------------- */ +/** \name Utilities + * \{ */ + +static bool editmesh_eval_final_is_bmesh(const BMEditMesh *em) +{ + return (em->mesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Snap Object Data * \{ */ @@ -360,7 +370,7 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx, * \{ */ typedef void (*IterSnapObjsCallback)(SnapObjectContext *sctx, - bool is_obedit, + bool use_obedit, bool use_backface_culling, Object *ob, float obmat[4][4], @@ -921,41 +931,52 @@ static bool raycastEditMesh(SnapObjectContext *sctx, return retval; } +struct RaycastObjUserData { + const float *ray_start; + const float *ray_dir; + uint ob_index; + /* read/write args */ + float *ray_depth; + /* return args */ + float *r_loc; + float *r_no; + int *r_index; + Object **r_ob; + float (*r_obmat)[4]; + ListBase *r_hit_list; + bool use_occlusion_test; + bool ret; +}; + /** * \param use_obedit: Uses the coordinates of BMesh (if any) to do the snapping; * * \note Duplicate args here are documented at #snapObjectsRay */ -static bool raycastObj(SnapObjectContext *sctx, - const float ray_start[3], - const float ray_dir[3], - Object *ob, - const float obmat[4][4], - const uint ob_index, - bool use_obedit, - bool use_occlusion_test, - bool use_backface_culling, - /* read/write args */ - float *ray_depth, - /* return args */ - float r_loc[3], - float r_no[3], - int *r_index, - Object **r_ob, - float r_obmat[4][4], - ListBase *r_hit_list) +static void raycast_obj_fn(SnapObjectContext *sctx, + bool use_obedit, + bool use_backface_culling, + Object *ob, + float obmat[4][4], + void *data) { + struct RaycastObjUserData *dt = data; + const uint ob_index = dt->ob_index++; + bool use_occlusion_test = dt->use_occlusion_test; + /* read/write args */ + float *ray_depth = dt->ray_depth; + bool retval = false; if (use_occlusion_test) { if (use_obedit && sctx->use_v3d && XRAY_FLAG_ENABLED(sctx->v3d_data.v3d)) { /* Use of occlude geometry in editing mode disabled. */ - return false; + return; } if (ELEM(ob->dt, OB_BOUNDBOX, OB_WIRE)) { /* Do not hit objects that are in wire or bounding box * display mode. */ - return false; + return; } } @@ -964,22 +985,22 @@ static bool raycastObj(SnapObjectContext *sctx, Mesh *me = ob->data; bool use_hide = false; if (BKE_object_is_in_editmode(ob)) { - if (use_obedit) { + if (use_obedit || editmesh_eval_final_is_bmesh(me->edit_mesh)) { /* Operators only update the editmesh looptris of the original mesh. */ BMEditMesh *em_orig = BKE_editmesh_from_object(DEG_get_original_object(ob)); retval = raycastEditMesh(sctx, - ray_start, - ray_dir, + dt->ray_start, + dt->ray_dir, ob, em_orig, obmat, ob_index, use_backface_culling, ray_depth, - r_loc, - r_no, - r_index, - r_hit_list); + dt->r_loc, + dt->r_no, + dt->r_index, + dt->r_hit_list); break; } else { @@ -991,8 +1012,8 @@ static bool raycastObj(SnapObjectContext *sctx, } } retval = raycastMesh(sctx, - ray_start, - ray_dir, + dt->ray_start, + dt->ray_dir, ob, me, obmat, @@ -1000,10 +1021,10 @@ static bool raycastObj(SnapObjectContext *sctx, use_hide, use_backface_culling, ray_depth, - r_loc, - r_no, - r_index, - r_hit_list); + dt->r_loc, + dt->r_no, + dt->r_index, + dt->r_hit_list); break; } case OB_CURVE: @@ -1012,8 +1033,8 @@ static bool raycastObj(SnapObjectContext *sctx, Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob); if (mesh_eval) { retval = raycastMesh(sctx, - ray_start, - ray_dir, + dt->ray_start, + dt->ray_dir, ob, mesh_eval, obmat, @@ -1021,70 +1042,24 @@ static bool raycastObj(SnapObjectContext *sctx, false, use_backface_culling, ray_depth, - r_loc, - r_no, - r_index, - r_hit_list); + dt->r_loc, + dt->r_no, + dt->r_index, + dt->r_hit_list); break; } } } if (retval) { - if (r_ob) { - *r_ob = ob; + if (dt->r_ob) { + *dt->r_ob = ob; } - if (r_obmat) { - copy_m4_m4(r_obmat, obmat); + if (dt->r_obmat) { + copy_m4_m4(dt->r_obmat, obmat); } - return true; + dt->ret = true; } - - return false; -} - -struct RaycastObjUserData { - const float *ray_start; - const float *ray_dir; - uint ob_index; - /* read/write args */ - float *ray_depth; - /* return args */ - float *r_loc; - float *r_no; - int *r_index; - Object **r_ob; - float (*r_obmat)[4]; - ListBase *r_hit_list; - bool use_occlusion_test; - bool ret; -}; - -static void raycast_obj_cb(SnapObjectContext *sctx, - bool use_obedit, - bool use_backface_culling, - Object *ob, - float obmat[4][4], - void *data) -{ - struct RaycastObjUserData *dt = data; - - dt->ret |= raycastObj(sctx, - dt->ray_start, - dt->ray_dir, - ob, - obmat, - dt->ob_index++, - use_obedit, - dt->use_occlusion_test, - use_backface_culling, - dt->ray_depth, - dt->r_loc, - dt->r_no, - dt->r_index, - dt->r_ob, - dt->r_obmat, - dt->r_hit_list); } /** @@ -1145,7 +1120,7 @@ static bool raycastObjects(SnapObjectContext *sctx, .ret = false, }; - iter_snap_objects(sctx, depsgraph, params, raycast_obj_cb, &data); + iter_snap_objects(sctx, depsgraph, params, raycast_obj_fn, &data); return data.ret; } @@ -1707,8 +1682,14 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, &nearest.dist_sq, nearest.co)) { nearest.index = vindex[v_id]; - nearest2d.copy_vert_no(vindex[v_id], nearest.no, nearest2d.userdata); elem = SCE_SNAP_MODE_VERTEX; + if (r_no) { + float imat[4][4]; + invert_m4_m4(imat, obmat); + nearest2d.copy_vert_no(vindex[v_id], r_no, nearest2d.userdata); + mul_transposed_mat3_m4_v3(imat, r_no); + normalize_v3(r_no); + } } } } @@ -1726,10 +1707,6 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, vmid, &nearest.dist_sq, nearest.co)) { - float v_nor[2][3]; - nearest2d.copy_vert_no(vindex[0], v_nor[0], nearest2d.userdata); - nearest2d.copy_vert_no(vindex[1], v_nor[1], nearest2d.userdata); - mid_v3_v3v3(nearest.no, v_nor[0], v_nor[1]); nearest.index = *r_index; elem = SCE_SNAP_MODE_EDGE_MIDPOINT; } @@ -1757,11 +1734,6 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, v_near, &nearest.dist_sq, nearest.co)) { - float v_nor[2][3]; - nearest2d.copy_vert_no(vindex[0], v_nor[0], nearest2d.userdata); - nearest2d.copy_vert_no(vindex[1], v_nor[1], nearest2d.userdata); - mid_v3_v3v3(nearest.no, v_nor[0], v_nor[1]); - nearest.index = *r_index; elem = SCE_SNAP_MODE_EDGE_PERPENDICULAR; } @@ -1778,15 +1750,6 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, mul_m4_v3(obmat, r_loc); } - if (r_no) { - float imat[4][4]; - invert_m4_m4(imat, obmat); - - copy_v3_v3(r_no, nearest.no); - mul_transposed_mat3_m4_v3(imat, r_no); - normalize_v3(r_no); - } - *r_index = nearest.index; } @@ -2657,45 +2620,51 @@ static short snapEditMesh(SnapObjectContext *sctx, return 0; } +struct SnapObjUserData { + SnapData *snapdata; + /* read/write args */ + float *dist_px; + /* return args */ + float *r_loc; + float *r_no; + int *r_index; + Object **r_ob; + float (*r_obmat)[4]; + short ret; +}; + /** * \param use_obedit: Uses the coordinates of BMesh (if any) to do the snapping; * * \note Duplicate args here are documented at #snapObjectsRay */ -static short snapObject(SnapObjectContext *sctx, - SnapData *snapdata, - Object *ob, - float obmat[4][4], +static void sanp_obj_fn(SnapObjectContext *sctx, bool use_obedit, bool use_backface_culling, - /* read/write args */ - float *dist_px, - /* return args */ - float r_loc[3], - float r_no[3], - int *r_index, - Object **r_ob, - float r_obmat[4][4]) + Object *ob, + float obmat[4][4], + void *data) { + struct SnapObjUserData *dt = data; short retval = 0; switch (ob->type) { case OB_MESH: { Mesh *me = ob->data; if (BKE_object_is_in_editmode(ob)) { - if (use_obedit) { + if (use_obedit || editmesh_eval_final_is_bmesh(me->edit_mesh)) { /* Operators only update the editmesh looptris of the original mesh. */ BMEditMesh *em_orig = BKE_editmesh_from_object(DEG_get_original_object(ob)); retval = snapEditMesh(sctx, - snapdata, + dt->snapdata, ob, em_orig, obmat, use_backface_culling, - dist_px, - r_loc, - r_no, - r_index); + dt->dist_px, + dt->r_loc, + dt->r_no, + dt->r_index); break; } else { @@ -2707,99 +2676,66 @@ static short snapObject(SnapObjectContext *sctx, } else if (ob->dt == OB_BOUNDBOX) { /* Do not snap to objects that are in bounding box display mode */ - return 0; + return; } - retval = snapMesh( - sctx, snapdata, ob, me, obmat, use_backface_culling, dist_px, r_loc, r_no, r_index); + retval = snapMesh(sctx, + dt->snapdata, + ob, + me, + obmat, + use_backface_culling, + dt->dist_px, + dt->r_loc, + dt->r_no, + dt->r_index); break; } case OB_ARMATURE: - retval = snapArmature(snapdata, ob, obmat, use_obedit, dist_px, r_loc, r_no, r_index); + retval = snapArmature( + dt->snapdata, ob, obmat, use_obedit, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index); break; case OB_CURVE: - retval = snapCurve(snapdata, ob, obmat, use_obedit, dist_px, r_loc, r_no, r_index); + retval = snapCurve( + dt->snapdata, ob, obmat, use_obedit, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index); break; /* Use ATTR_FALLTHROUGH if we want to snap to the generated mesh. */ case OB_SURF: case OB_FONT: { Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob); if (mesh_eval) { retval |= snapMesh(sctx, - snapdata, + dt->snapdata, ob, mesh_eval, obmat, use_backface_culling, - dist_px, - r_loc, - r_no, - r_index); + dt->dist_px, + dt->r_loc, + dt->r_no, + dt->r_index); } break; } case OB_EMPTY: - retval = snapEmpty(snapdata, ob, obmat, dist_px, r_loc, r_no, r_index); + retval = snapEmpty(dt->snapdata, ob, obmat, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index); break; case OB_GPENCIL: - retval = snapEmpty(snapdata, ob, obmat, dist_px, r_loc, r_no, r_index); + retval = snapEmpty(dt->snapdata, ob, obmat, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index); break; case OB_CAMERA: - retval = snapCamera(sctx, snapdata, ob, obmat, dist_px, r_loc, r_no, r_index); + retval = snapCamera( + sctx, dt->snapdata, ob, obmat, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index); break; } if (retval) { - if (r_ob) { - *r_ob = ob; + if (dt->r_ob) { + *dt->r_ob = ob; } - if (r_obmat) { - copy_m4_m4(r_obmat, obmat); + if (dt->r_obmat) { + copy_m4_m4(dt->r_obmat, obmat); } - return retval; - } - - return 0; -} - -struct SnapObjUserData { - SnapData *snapdata; - /* read/write args */ - float *dist_px; - /* return args */ - float *r_loc; - float *r_no; - int *r_index; - Object **r_ob; - float (*r_obmat)[4]; - short ret; -}; - -static void sanp_obj_cb(SnapObjectContext *sctx, - bool is_obedit, - bool use_backface_culling, - Object *ob, - float obmat[4][4], - void *data) -{ - struct SnapObjUserData *dt = data; - - short elem = snapObject(sctx, - dt->snapdata, - ob, - obmat, - is_obedit, - use_backface_culling, - /* read/write args */ - dt->dist_px, - /* return args */ - dt->r_loc, - dt->r_no, - dt->r_index, - dt->r_ob, - dt->r_obmat); - - if (elem) { - dt->ret = elem; + dt->ret = retval; } } @@ -2852,7 +2788,7 @@ static short snapObjectsRay(SnapObjectContext *sctx, .ret = 0, }; - iter_snap_objects(sctx, depsgraph, params, sanp_obj_cb, &data); + iter_snap_objects(sctx, depsgraph, params, sanp_obj_fn, &data); return data.ret; } @@ -2863,13 +2799,12 @@ static short snapObjectsRay(SnapObjectContext *sctx, /** \name Public Object Snapping API * \{ */ -SnapObjectContext *ED_transform_snap_object_context_create(Main *bmain, Scene *scene, int flag) +SnapObjectContext *ED_transform_snap_object_context_create(Scene *scene, int flag) { SnapObjectContext *sctx = MEM_callocN(sizeof(*sctx), __func__); sctx->flag = flag; - sctx->bmain = bmain; sctx->scene = scene; sctx->cache.object_map = BLI_ghash_ptr_new(__func__); @@ -2880,14 +2815,13 @@ SnapObjectContext *ED_transform_snap_object_context_create(Main *bmain, Scene *s return sctx; } -SnapObjectContext *ED_transform_snap_object_context_create_view3d(Main *bmain, - Scene *scene, +SnapObjectContext *ED_transform_snap_object_context_create_view3d(Scene *scene, int flag, /* extra args for view3d */ const ARegion *region, const View3D *v3d) { - SnapObjectContext *sctx = ED_transform_snap_object_context_create(bmain, scene, flag); + SnapObjectContext *sctx = ED_transform_snap_object_context_create(scene, flag); sctx->use_v3d = true; sctx->v3d_data.region = region; |