Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/transform/transform_snap_object.c
| Show First 20 Lines • Show All 363 Lines • ▼ Show 20 Lines | |||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Iterator | /** \name Iterator | ||||
| * \{ */ | * \{ */ | ||||
| typedef void (*IterSnapObjsCallback)(SnapObjectContext *sctx, | typedef void (*IterSnapObjsCallback)(SnapObjectContext *sctx, | ||||
| Object *ob, | Object *ob, | ||||
| float obmat[4][4], | float obmat[4][4], | ||||
| const eSnapSelect snap_select, | |||||
| bool use_obedit, | bool use_obedit, | ||||
| bool use_backface_culling, | bool use_backface_culling, | ||||
| bool is_object_active, | bool is_object_active, | ||||
| void *data); | void *data); | ||||
| /** | /** | ||||
| * Walks through all objects in the scene to create the list of objects to snap. | * Walks through all objects in the scene to create the list of objects to snap. | ||||
| */ | */ | ||||
| Show All 10 Lines | static void iter_snap_objects(SnapObjectContext *sctx, | ||||
| const bool use_backface_culling = params->use_backface_culling; | const bool use_backface_culling = params->use_backface_culling; | ||||
| Base *base_act = view_layer->basact; | Base *base_act = view_layer->basact; | ||||
| for (Base *base = view_layer->object_bases.first; base != NULL; base = base->next) { | for (Base *base = view_layer->object_bases.first; base != NULL; base = base->next) { | ||||
| if (!BASE_VISIBLE(v3d, base)) { | if (!BASE_VISIBLE(v3d, base)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| if (base->flag_legacy & BA_TRANSFORM_LOCKED_IN_PLACE) { | if (ELEM(snap_select, SNAP_ALL, SNAP_SELECTED_ONLY) || base->flag_legacy & BA_TRANSFORM_LOCKED_IN_PLACE) { | ||||
| /* pass */ | /* pass */ | ||||
| } | } | ||||
| else if (base->flag_legacy & BA_SNAP_FIX_DEPS_FIASCO) { | else if (base->flag_legacy & BA_SNAP_FIX_DEPS_FIASCO) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| const bool is_object_active = (base == base_act); | const bool is_object_active = (base == base_act); | ||||
| if (snap_select == SNAP_NOT_ACTIVE) { | |||||
| if (is_object_active) { | |||||
| continue; | |||||
| } | |||||
| } | |||||
| else if (ELEM(snap_select, SNAP_NOT_SELECTED, SNAP_SELECTED_ONLY)) { | |||||
| bool is_selected = (base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL); | |||||
| if (is_selected) { | |||||
| if (snap_select == SNAP_NOT_SELECTED) { | if (snap_select == SNAP_NOT_SELECTED) { | ||||
| if ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)) { | |||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| else if (snap_select == SNAP_NOT_ACTIVE) { | else if (snap_select == SNAP_SELECTED_ONLY) { | ||||
| if (is_object_active) { | |||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| Object *obj_eval = DEG_get_evaluated_object(depsgraph, base->object); | Object *obj_eval = DEG_get_evaluated_object(depsgraph, base->object); | ||||
| if (obj_eval->transflag & OB_DUPLI) { | if (obj_eval->transflag & OB_DUPLI) { | ||||
| DupliObject *dupli_ob; | DupliObject *dupli_ob; | ||||
| ListBase *lb = object_duplilist(depsgraph, sctx->scene, obj_eval); | ListBase *lb = object_duplilist(depsgraph, sctx->scene, obj_eval); | ||||
| for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { | for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { | ||||
| sob_callback(sctx, | sob_callback(sctx, | ||||
| dupli_ob->ob, | dupli_ob->ob, | ||||
| dupli_ob->mat, | dupli_ob->mat, | ||||
| snap_select, | |||||
| use_object_edit_cage, | use_object_edit_cage, | ||||
| use_backface_culling, | use_backface_culling, | ||||
| is_object_active, | is_object_active, | ||||
| data); | data); | ||||
| } | } | ||||
| free_object_duplilist(lb); | free_object_duplilist(lb); | ||||
| } | } | ||||
| sob_callback(sctx, | sob_callback(sctx, | ||||
| obj_eval, | obj_eval, | ||||
| obj_eval->obmat, | obj_eval->obmat, | ||||
| snap_select, | |||||
| use_object_edit_cage, | use_object_edit_cage, | ||||
| use_backface_culling, | use_backface_culling, | ||||
| is_object_active, | is_object_active, | ||||
| data); | data); | ||||
| } | } | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| ▲ Show 20 Lines • Show All 517 Lines • ▼ Show 20 Lines | |||||
| /** | /** | ||||
| * \param use_obedit: Uses the coordinates of BMesh (if any) to do the snapping; | * \param use_obedit: Uses the coordinates of BMesh (if any) to do the snapping; | ||||
| * | * | ||||
| * \note Duplicate args here are documented at #snapObjectsRay | * \note Duplicate args here are documented at #snapObjectsRay | ||||
| */ | */ | ||||
| static void raycast_obj_fn(SnapObjectContext *sctx, | static void raycast_obj_fn(SnapObjectContext *sctx, | ||||
| Object *ob, | Object *ob, | ||||
| float obmat[4][4], | float obmat[4][4], | ||||
| const eSnapSelect UNUSED(snap_select), | |||||
| bool use_obedit, | bool use_obedit, | ||||
| bool use_backface_culling, | bool use_backface_culling, | ||||
| bool is_object_active, | bool is_object_active, | ||||
| void *data) | void *data) | ||||
| { | { | ||||
| struct RaycastObjUserData *dt = data; | struct RaycastObjUserData *dt = data; | ||||
| const uint ob_index = dt->ob_index++; | const uint ob_index = dt->ob_index++; | ||||
| bool use_occlusion_test = dt->use_occlusion_test; | bool use_occlusion_test = dt->use_occlusion_test; | ||||
| ▲ Show 20 Lines • Show All 789 Lines • ▼ Show 20 Lines | static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, | ||||
| } | } | ||||
| return elem; | return elem; | ||||
| } | } | ||||
| static short snapArmature(SnapData *snapdata, | static short snapArmature(SnapData *snapdata, | ||||
| Object *ob, | Object *ob, | ||||
| const float obmat[4][4], | const float obmat[4][4], | ||||
| const eSnapSelect snap_select, | |||||
| bool use_obedit, | bool use_obedit, | ||||
| /* read/write args */ | /* read/write args */ | ||||
| float *dist_px, | float *dist_px, | ||||
| /* return args */ | /* return args */ | ||||
| float r_loc[3], | float r_loc[3], | ||||
| float *UNUSED(r_no), | float *UNUSED(r_no), | ||||
| int *r_index) | int *r_index) | ||||
| { | { | ||||
| Show All 28 Lines | static short snapArmature(SnapData *snapdata, | ||||
| } | } | ||||
| bool is_persp = snapdata->view_proj == VIEW_PROJ_PERSP; | bool is_persp = snapdata->view_proj == VIEW_PROJ_PERSP; | ||||
| bArmature *arm = ob->data; | bArmature *arm = ob->data; | ||||
| if (arm->edbo) { | if (arm->edbo) { | ||||
| LISTBASE_FOREACH (EditBone *, eBone, arm->edbo) { | LISTBASE_FOREACH (EditBone *, eBone, arm->edbo) { | ||||
| if (eBone->layer & arm->layer) { | if (eBone->layer & arm->layer) { | ||||
| /* skip hidden or moving (selected) bones */ | if (eBone->flag & BONE_HIDDEN_A) { | ||||
| if ((eBone->flag & (BONE_HIDDEN_A | BONE_ROOTSEL | BONE_TIPSEL)) == 0) { | /* Skip hidden bones. */ | ||||
| continue; | |||||
| } | |||||
| const bool is_selected = (eBone->flag & (BONE_ROOTSEL | BONE_TIPSEL)) != 0; | |||||
| if (is_selected && snap_select == SNAP_NOT_SELECTED) { | |||||
| continue; | |||||
| } | |||||
| if (!is_selected && snap_select == SNAP_SELECTED_ONLY) { | |||||
| continue; | |||||
| } | |||||
| bool has_vert_snap = false; | bool has_vert_snap = false; | ||||
| if (snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX) { | if (snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX) { | ||||
| has_vert_snap = test_projected_vert_dist(&neasrest_precalc, | has_vert_snap = test_projected_vert_dist(&neasrest_precalc, | ||||
| clip_planes_local, | clip_planes_local, | ||||
| snapdata->clip_plane_len, | snapdata->clip_plane_len, | ||||
| is_persp, | is_persp, | ||||
| eBone->head, | eBone->head, | ||||
| &dist_px_sq, | &dist_px_sq, | ||||
| r_loc); | r_loc); | ||||
| has_vert_snap |= test_projected_vert_dist(&neasrest_precalc, | has_vert_snap |= test_projected_vert_dist(&neasrest_precalc, | ||||
| clip_planes_local, | clip_planes_local, | ||||
| snapdata->clip_plane_len, | snapdata->clip_plane_len, | ||||
| is_persp, | is_persp, | ||||
| eBone->tail, | eBone->tail, | ||||
| &dist_px_sq, | &dist_px_sq, | ||||
| r_loc); | r_loc); | ||||
| if (has_vert_snap) { | if (has_vert_snap) { | ||||
| retval = SCE_SNAP_MODE_VERTEX; | retval = SCE_SNAP_MODE_VERTEX; | ||||
| } | } | ||||
| } | } | ||||
| if (!has_vert_snap && snapdata->snap_to_flag & SCE_SNAP_MODE_EDGE) { | if (!has_vert_snap && snapdata->snap_to_flag & SCE_SNAP_MODE_EDGE) { | ||||
| if (test_projected_edge_dist(&neasrest_precalc, | if (test_projected_edge_dist(&neasrest_precalc, | ||||
| clip_planes_local, | clip_planes_local, | ||||
| snapdata->clip_plane_len, | snapdata->clip_plane_len, | ||||
| is_persp, | is_persp, | ||||
| eBone->head, | eBone->head, | ||||
| eBone->tail, | eBone->tail, | ||||
| &dist_px_sq, | &dist_px_sq, | ||||
| r_loc)) { | r_loc)) { | ||||
| retval = SCE_SNAP_MODE_EDGE; | retval = SCE_SNAP_MODE_EDGE; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| else if (ob->pose && ob->pose->chanbase.first) { | else if (ob->pose && ob->pose->chanbase.first) { | ||||
| LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { | LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { | ||||
| Bone *bone = pchan->bone; | Bone *bone = pchan->bone; | ||||
| /* skip hidden bones */ | /* skip hidden bones */ | ||||
| if (bone && !(bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) { | if (bone && !(bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) { | ||||
| continue; | |||||
| } | |||||
| bool has_vert_snap = false; | bool has_vert_snap = false; | ||||
| const float *head_vec = pchan->pose_head; | const float *head_vec = pchan->pose_head; | ||||
| const float *tail_vec = pchan->pose_tail; | const float *tail_vec = pchan->pose_tail; | ||||
| if (snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX) { | if (snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX) { | ||||
| has_vert_snap = test_projected_vert_dist(&neasrest_precalc, | has_vert_snap = test_projected_vert_dist(&neasrest_precalc, | ||||
| clip_planes_local, | clip_planes_local, | ||||
| snapdata->clip_plane_len, | snapdata->clip_plane_len, | ||||
| is_persp, | is_persp, | ||||
| head_vec, | head_vec, | ||||
| &dist_px_sq, | &dist_px_sq, | ||||
| r_loc); | r_loc); | ||||
| has_vert_snap |= test_projected_vert_dist(&neasrest_precalc, | has_vert_snap |= test_projected_vert_dist(&neasrest_precalc, | ||||
| clip_planes_local, | clip_planes_local, | ||||
| snapdata->clip_plane_len, | snapdata->clip_plane_len, | ||||
| is_persp, | is_persp, | ||||
| tail_vec, | tail_vec, | ||||
| &dist_px_sq, | &dist_px_sq, | ||||
| r_loc); | r_loc); | ||||
| if (has_vert_snap) { | if (has_vert_snap) { | ||||
| retval = SCE_SNAP_MODE_VERTEX; | retval = SCE_SNAP_MODE_VERTEX; | ||||
| } | } | ||||
| } | } | ||||
| if (!has_vert_snap && snapdata->snap_to_flag & SCE_SNAP_MODE_EDGE) { | if (!has_vert_snap && snapdata->snap_to_flag & SCE_SNAP_MODE_EDGE) { | ||||
| if (test_projected_edge_dist(&neasrest_precalc, | if (test_projected_edge_dist(&neasrest_precalc, | ||||
| clip_planes_local, | clip_planes_local, | ||||
| snapdata->clip_plane_len, | snapdata->clip_plane_len, | ||||
| is_persp, | is_persp, | ||||
| head_vec, | head_vec, | ||||
| tail_vec, | tail_vec, | ||||
| &dist_px_sq, | &dist_px_sq, | ||||
| r_loc)) { | r_loc)) { | ||||
| retval = SCE_SNAP_MODE_EDGE; | retval = SCE_SNAP_MODE_EDGE; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| if (retval) { | if (retval) { | ||||
| *dist_px = sqrtf(dist_px_sq); | *dist_px = sqrtf(dist_px_sq); | ||||
| mul_m4_v3(obmat, r_loc); | mul_m4_v3(obmat, r_loc); | ||||
| if (r_index) { | if (r_index) { | ||||
| /* Does not support index. */ | /* Does not support index. */ | ||||
| *r_index = -1; | *r_index = -1; | ||||
| } | } | ||||
| return retval; | return retval; | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| static short snapCurve(SnapData *snapdata, | static short snapCurve(SnapData *snapdata, | ||||
| Object *ob, | Object *ob, | ||||
| const float obmat[4][4], | const float obmat[4][4], | ||||
| const eSnapSelect snap_select, | |||||
| bool use_obedit, | bool use_obedit, | ||||
| /* read/write args */ | /* read/write args */ | ||||
| float *dist_px, | float *dist_px, | ||||
| /* return args */ | /* return args */ | ||||
| float r_loc[3], | float r_loc[3], | ||||
| float *UNUSED(r_no), | float *UNUSED(r_no), | ||||
| int *r_index) | int *r_index) | ||||
| { | { | ||||
| Show All 38 Lines | static short snapCurve(SnapData *snapdata, | ||||
| } | } | ||||
| float clip_planes_local[MAX_CLIPPLANE_LEN][4]; | float clip_planes_local[MAX_CLIPPLANE_LEN][4]; | ||||
| for (int i = clip_plane_len; i--;) { | for (int i = clip_plane_len; i--;) { | ||||
| mul_v4_m4v4(clip_planes_local[i], tobmat, clip_planes[i]); | mul_v4_m4v4(clip_planes_local[i], tobmat, clip_planes[i]); | ||||
| } | } | ||||
| bool is_persp = snapdata->view_proj == VIEW_PROJ_PERSP; | bool is_persp = snapdata->view_proj == VIEW_PROJ_PERSP; | ||||
| bool skip_selected = snap_select == SNAP_NOT_SELECTED; | |||||
| bool skip_unselected = snap_select == SNAP_SELECTED_ONLY; | |||||
| for (Nurb *nu = (use_obedit ? cu->editnurb->nurbs.first : cu->nurb.first); nu; nu = nu->next) { | for (Nurb *nu = (use_obedit ? cu->editnurb->nurbs.first : cu->nurb.first); nu; nu = nu->next) { | ||||
| for (int u = 0; u < nu->pntsu; u++) { | for (int u = 0; u < nu->pntsu; u++) { | ||||
| if (snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX) { | if (snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX) { | ||||
| if (use_obedit) { | if (use_obedit) { | ||||
| if (nu->bezt) { | if (nu->bezt) { | ||||
| /* don't snap to selected (moving) or hidden */ | if (nu->bezt[u].hide) { | ||||
| if (nu->bezt[u].f2 & SELECT || nu->bezt[u].hide != 0) { | /* Skip hidden. */ | ||||
| continue; | |||||
| } | |||||
| bool is_selected = (nu->bezt[u].f2 & SELECT) != 0; | |||||
| if (is_selected && skip_selected) { | |||||
| continue; | |||||
| } | |||||
| if (!is_selected && skip_unselected) { | |||||
| continue; | continue; | ||||
| } | } | ||||
| has_snap |= test_projected_vert_dist(&neasrest_precalc, | has_snap |= test_projected_vert_dist(&neasrest_precalc, | ||||
| clip_planes_local, | clip_planes_local, | ||||
| clip_plane_len, | clip_plane_len, | ||||
| is_persp, | is_persp, | ||||
| nu->bezt[u].vec[1], | nu->bezt[u].vec[1], | ||||
| &dist_px_sq, | &dist_px_sq, | ||||
| r_loc); | r_loc); | ||||
| /* Don't snap if handle is selected (moving), | /* Don't snap if handle is selected (moving), | ||||
| * or if it is aligning to a moving handle. */ | * or if it is aligning to a moving handle. */ | ||||
| if (!(nu->bezt[u].f1 & SELECT) && | is_selected = (!(nu->bezt[u].f1 & SELECT) && | ||||
| !(nu->bezt[u].h1 & HD_ALIGN && nu->bezt[u].f3 & SELECT)) { | !(nu->bezt[u].h1 & HD_ALIGN && nu->bezt[u].f3 & SELECT)) != 0; | ||||
| if (!(is_selected && skip_selected) && !(!is_selected && skip_unselected)) { | |||||
| has_snap |= test_projected_vert_dist(&neasrest_precalc, | has_snap |= test_projected_vert_dist(&neasrest_precalc, | ||||
| clip_planes_local, | clip_planes_local, | ||||
| clip_plane_len, | clip_plane_len, | ||||
| is_persp, | is_persp, | ||||
| nu->bezt[u].vec[0], | nu->bezt[u].vec[0], | ||||
| &dist_px_sq, | &dist_px_sq, | ||||
| r_loc); | r_loc); | ||||
| } | } | ||||
| if (!(nu->bezt[u].f3 & SELECT) && | |||||
| !(nu->bezt[u].h2 & HD_ALIGN && nu->bezt[u].f1 & SELECT)) { | is_selected = (!(nu->bezt[u].f3 & SELECT) && | ||||
| !(nu->bezt[u].h2 & HD_ALIGN && nu->bezt[u].f1 & SELECT)) != 0; | |||||
| if (!(is_selected && skip_selected) && !(!is_selected && skip_unselected)) { | |||||
| has_snap |= test_projected_vert_dist(&neasrest_precalc, | has_snap |= test_projected_vert_dist(&neasrest_precalc, | ||||
| clip_planes_local, | clip_planes_local, | ||||
| clip_plane_len, | clip_plane_len, | ||||
| is_persp, | is_persp, | ||||
| nu->bezt[u].vec[2], | nu->bezt[u].vec[2], | ||||
| &dist_px_sq, | &dist_px_sq, | ||||
| r_loc); | r_loc); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* don't snap to selected (moving) or hidden */ | if (nu->bp[u].hide) { | ||||
| if (nu->bp[u].f1 & SELECT || nu->bp[u].hide != 0) { | /* Skip hidden. */ | ||||
| continue; | |||||
| } | |||||
| bool is_selected = (nu->bp[u].f1 & SELECT) != 0; | |||||
| if (is_selected && skip_selected) { | |||||
| continue; | continue; | ||||
| } | } | ||||
| if (!is_selected && skip_unselected) { | |||||
| continue; | |||||
| } | |||||
| has_snap |= test_projected_vert_dist(&neasrest_precalc, | has_snap |= test_projected_vert_dist(&neasrest_precalc, | ||||
| clip_planes_local, | clip_planes_local, | ||||
| clip_plane_len, | clip_plane_len, | ||||
| is_persp, | is_persp, | ||||
| nu->bp[u].vec, | nu->bp[u].vec, | ||||
| &dist_px_sq, | &dist_px_sq, | ||||
| r_loc); | r_loc); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 632 Lines • ▼ Show 20 Lines | |||||
| /** | /** | ||||
| * \param use_obedit: Uses the coordinates of BMesh (if any) to do the snapping; | * \param use_obedit: Uses the coordinates of BMesh (if any) to do the snapping; | ||||
| * | * | ||||
| * \note Duplicate args here are documented at #snapObjectsRay | * \note Duplicate args here are documented at #snapObjectsRay | ||||
| */ | */ | ||||
| static void snap_obj_fn(SnapObjectContext *sctx, | static void snap_obj_fn(SnapObjectContext *sctx, | ||||
| Object *ob, | Object *ob, | ||||
| float obmat[4][4], | float obmat[4][4], | ||||
| const eSnapSelect snap_select, | |||||
| bool use_obedit, | bool use_obedit, | ||||
| bool use_backface_culling, | bool use_backface_culling, | ||||
| bool UNUSED(is_object_active), | bool UNUSED(is_object_active), | ||||
| void *data) | void *data) | ||||
| { | { | ||||
| struct SnapObjUserData *dt = data; | struct SnapObjUserData *dt = data; | ||||
| short retval = 0; | short retval = 0; | ||||
| Show All 35 Lines | case OB_MESH: { | ||||
| use_backface_culling, | use_backface_culling, | ||||
| dt->dist_px, | dt->dist_px, | ||||
| dt->r_loc, | dt->r_loc, | ||||
| dt->r_no, | dt->r_no, | ||||
| dt->r_index); | dt->r_index); | ||||
| break; | break; | ||||
| } | } | ||||
| case OB_ARMATURE: | case OB_ARMATURE: | ||||
| retval = snapArmature( | retval = snapArmature(dt->snapdata, | ||||
| dt->snapdata, ob, obmat, use_obedit, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index); | ob, | ||||
| obmat, | |||||
| snap_select, | |||||
| use_obedit, | |||||
| dt->dist_px, | |||||
| dt->r_loc, | |||||
| dt->r_no, | |||||
| dt->r_index); | |||||
| break; | break; | ||||
| case OB_CURVE: | case OB_CURVE: | ||||
| retval = snapCurve( | retval = snapCurve(dt->snapdata, | ||||
| dt->snapdata, ob, obmat, use_obedit, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index); | ob, | ||||
| obmat, | |||||
| snap_select, | |||||
| 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. */ | break; /* Use ATTR_FALLTHROUGH if we want to snap to the generated mesh. */ | ||||
| case OB_SURF: | case OB_SURF: | ||||
| case OB_FONT: { | case OB_FONT: { | ||||
| Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob); | Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob); | ||||
| if (mesh_eval) { | if (mesh_eval) { | ||||
| retval |= snapMesh(sctx, | retval |= snapMesh(sctx, | ||||
| dt->snapdata, | dt->snapdata, | ||||
| ob, | ob, | ||||
| ▲ Show 20 Lines • Show All 135 Lines • ▼ Show 20 Lines | void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx) | ||||
| if (sctx->cache.data_to_object_map != NULL) { | if (sctx->cache.data_to_object_map != NULL) { | ||||
| BLI_ghash_free(sctx->cache.data_to_object_map, NULL, NULL); | BLI_ghash_free(sctx->cache.data_to_object_map, NULL, NULL); | ||||
| } | } | ||||
| BLI_memarena_free(sctx->cache.mem_arena); | BLI_memarena_free(sctx->cache.mem_arena); | ||||
| MEM_freeN(sctx); | MEM_freeN(sctx); | ||||
| } | } | ||||
| static void transform_snap_object_context_cache_clear(SnapObjectContext *sctx) | |||||
| { | |||||
| BLI_ghash_clear(sctx->cache.object_map, NULL, snap_object_data_free); | |||||
| if (sctx->cache.data_to_object_map != NULL) { | |||||
| BLI_ghash_clear(sctx->cache.data_to_object_map, NULL, NULL); | |||||
| } | |||||
| BLI_memarena_clear(sctx->cache.mem_arena); | |||||
| } | |||||
| void ED_transform_snap_object_context_set_editmesh_callbacks( | void ED_transform_snap_object_context_set_editmesh_callbacks( | ||||
| SnapObjectContext *sctx, | SnapObjectContext *sctx, | ||||
| bool (*test_vert_fn)(BMVert *, void *user_data), | bool (*test_vert_fn)(BMVert *, void *user_data), | ||||
| bool (*test_edge_fn)(BMEdge *, void *user_data), | bool (*test_edge_fn)(BMEdge *, void *user_data), | ||||
| bool (*test_face_fn)(BMFace *, void *user_data), | bool (*test_face_fn)(BMFace *, void *user_data), | ||||
| void *user_data) | void *user_data) | ||||
| { | { | ||||
| bool is_cache_dirty = false; | |||||
| if (sctx->callbacks.edit_mesh.test_vert_fn != test_vert_fn) { | |||||
| sctx->callbacks.edit_mesh.test_vert_fn = test_vert_fn; | sctx->callbacks.edit_mesh.test_vert_fn = test_vert_fn; | ||||
| is_cache_dirty = true; | |||||
| } | |||||
| if (sctx->callbacks.edit_mesh.test_edge_fn != test_edge_fn) { | |||||
| sctx->callbacks.edit_mesh.test_edge_fn = test_edge_fn; | sctx->callbacks.edit_mesh.test_edge_fn = test_edge_fn; | ||||
| is_cache_dirty = true; | |||||
| } | |||||
| if (sctx->callbacks.edit_mesh.test_face_fn != test_face_fn) { | |||||
| sctx->callbacks.edit_mesh.test_face_fn = test_face_fn; | sctx->callbacks.edit_mesh.test_face_fn = test_face_fn; | ||||
| is_cache_dirty = true; | |||||
| } | |||||
| if (sctx->callbacks.edit_mesh.user_data != user_data) { | |||||
| sctx->callbacks.edit_mesh.user_data = user_data; | sctx->callbacks.edit_mesh.user_data = user_data; | ||||
| is_cache_dirty = true; | |||||
| } | |||||
| if (is_cache_dirty) { | |||||
| transform_snap_object_context_cache_clear(sctx); | |||||
| } | |||||
| } | } | ||||
| bool ED_transform_snap_object_project_ray_ex(SnapObjectContext *sctx, | bool ED_transform_snap_object_project_ray_ex(SnapObjectContext *sctx, | ||||
| Depsgraph *depsgraph, | Depsgraph *depsgraph, | ||||
| const struct SnapObjectParams *params, | const struct SnapObjectParams *params, | ||||
| const float ray_start[3], | const float ray_start[3], | ||||
| const float ray_normal[3], | const float ray_normal[3], | ||||
| float *ray_depth, | float *ray_depth, | ||||
| ▲ Show 20 Lines • Show All 383 Lines • Show Last 20 Lines | |||||