diff options
author | Campbell Barton <ideasman42@gmail.com> | 2016-04-21 04:29:32 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2016-04-22 09:36:53 +0300 |
commit | 19e5540ff7712a45ab4ced4a4a02b12ce02637a9 (patch) | |
tree | b43be4638a05372d802dc71580099e53f54545bc /source/blender/editors/transform/transform_snap.c | |
parent | 8dcdde52b17228601c95fed04f5bca03484d27ac (diff) |
Transform Snap: initial snap context refactor
This introduces a snap-context that can be re-used for casting rays into the scene
(by operators such as walk-mode, ruler and transform code).
This can be used to cache data between calls too.
Diffstat (limited to 'source/blender/editors/transform/transform_snap.c')
-rw-r--r-- | source/blender/editors/transform/transform_snap.c | 914 |
1 files changed, 32 insertions, 882 deletions
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index bb9120c337b..9e8454bf6fb 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -36,8 +36,6 @@ #include "PIL_time.h" -#include "DNA_armature_types.h" -#include "DNA_curve_types.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" #include "DNA_meshdata_types.h" /* Temporary, for snapping to other unselected meshes */ @@ -61,13 +59,11 @@ #include "BKE_editmesh.h" #include "BKE_sequencer.h" #include "BKE_main.h" -#include "BKE_tracking.h" #include "RNA_access.h" #include "WM_types.h" -#include "ED_armature.h" #include "ED_image.h" #include "ED_node.h" #include "ED_uvedit.h" @@ -83,10 +79,6 @@ /* this should be passed as an arg for use in snap functions */ #undef BASACT -#define TRANSFORM_DIST_MAX_PX 1000.0f -#define TRANSFORM_SNAP_MAX_PX 100.0f -#define TRANSFORM_DIST_INVALID -FLT_MAX - /* use half of flt-max so we can scale up without an exception */ /********************* PROTOTYPES ***********************/ @@ -331,8 +323,8 @@ void applyProject(TransInfo *t) if (ED_view3d_project_float_global(t->ar, iloc, mval_fl, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { if (snapObjectsTransform( - t, mval_fl, t->tsnap.modeSelect, - loc, no, &dist_px)) + t, mval_fl, t->tsnap.modeSelect, &dist_px, + loc, no)) { // if (t->flag & (T_EDIT|T_POSE)) { // mul_m4_v3(imat, loc); @@ -573,6 +565,14 @@ static void initSnappingMode(TransInfo *t) /* Always grid outside of 3D view */ t->tsnap.mode = SCE_SNAP_MODE_INCREMENT; } + + if (t->flag & (T_OBJECT | T_EDIT)) { + if (t->spacetype == SPACE_VIEW3D) { + t->tsnap.object_context = ED_transform_snap_object_context_create_view3d( + G.main, t->scene, SNAP_OBJECT_USE_CACHE, + t->ar, t->view); + } + } } void initSnapping(TransInfo *t, wmOperator *op) @@ -636,6 +636,14 @@ void initSnapping(TransInfo *t, wmOperator *op) initSnappingMode(t); } +void freeSnapping(TransInfo *t) +{ + if (t->tsnap.object_context) { + ED_transform_snap_object_context_destroy(t->tsnap.object_context); + t->tsnap.object_context = NULL; + } +} + static void setSnappingCallback(TransInfo *t) { t->tsnap.calcSnap = CalcSnapGeometry; @@ -1002,8 +1010,8 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec)) else { zero_v3(no); /* objects won't set this */ found = snapObjectsTransform( - t, mval, t->tsnap.modeSelect, - loc, no, &dist_px); + t, mval, t->tsnap.modeSelect, &dist_px, + loc, no); } if (found == true) { @@ -1237,884 +1245,26 @@ static void TargetSnapClosest(TransInfo *t) } } -static bool snapEdge( - ARegion *ar, const float v1co[3], const short v1no[3], const float v2co[3], const short v2no[3], - float obmat[4][4], float timat[3][3], const float mval_fl[2], - const float ray_start[3], const float ray_start_local[3], const float ray_normal_local[3], float *ray_depth, - float r_loc[3], float r_no[3], float *r_dist_px) -{ - float intersect[3] = {0, 0, 0}, ray_end[3], dvec[3]; - int result; - bool retval = false; - - copy_v3_v3(ray_end, ray_normal_local); - mul_v3_fl(ray_end, 2000); - add_v3_v3v3(ray_end, ray_start_local, ray_end); - - result = isect_line_line_v3(v1co, v2co, ray_start_local, ray_end, intersect, dvec); /* dvec used but we don't care about result */ - - if (result) { - float edge_loc[3], vec[3]; - float mul; - - /* check for behind ray_start */ - sub_v3_v3v3(dvec, intersect, ray_start_local); - - sub_v3_v3v3(edge_loc, v1co, v2co); - sub_v3_v3v3(vec, intersect, v2co); - - mul = dot_v3v3(vec, edge_loc) / dot_v3v3(edge_loc, edge_loc); - - if (mul > 1) { - mul = 1; - copy_v3_v3(intersect, v1co); - } - else if (mul < 0) { - mul = 0; - copy_v3_v3(intersect, v2co); - } - - if (dot_v3v3(ray_normal_local, dvec) > 0) { - float location[3]; - float new_depth; - float screen_loc[2]; - float new_dist; - - copy_v3_v3(location, intersect); - - mul_m4_v3(obmat, location); - - new_depth = len_v3v3(location, ray_start); - - if (ED_view3d_project_float_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { - new_dist = len_manhattan_v2v2(mval_fl, screen_loc); - } - else { - new_dist = TRANSFORM_DIST_MAX_PX; - } - - /* 10% threshold if edge is closer but a bit further - * this takes care of series of connected edges a bit slanted w.r.t the viewport - * otherwise, it would stick to the verts of the closest edge and not slide along merrily - * */ - if (new_dist <= *r_dist_px && new_depth < *ray_depth * 1.001f) { - float n1[3], n2[3]; - - *ray_depth = new_depth; - retval = true; - - sub_v3_v3v3(edge_loc, v1co, v2co); - sub_v3_v3v3(vec, intersect, v2co); - - mul = dot_v3v3(vec, edge_loc) / dot_v3v3(edge_loc, edge_loc); - - if (r_no) { - normal_short_to_float_v3(n1, v1no); - normal_short_to_float_v3(n2, v2no); - interp_v3_v3v3(r_no, n2, n1, mul); - mul_m3_v3(timat, r_no); - normalize_v3(r_no); - } - - copy_v3_v3(r_loc, location); - - *r_dist_px = new_dist; - } - } - } - - return retval; -} - -static bool snapVertex( - ARegion *ar, const float vco[3], const short vno[3], - float obmat[4][4], float timat[3][3], const float mval_fl[2], - const float ray_start[3], const float ray_start_local[3], const float ray_normal_local[3], float *ray_depth, - float r_loc[3], float r_no[3], float *r_dist_px) -{ - bool retval = false; - float dvec[3]; - - sub_v3_v3v3(dvec, vco, ray_start_local); - - if (dot_v3v3(ray_normal_local, dvec) > 0) { - float location[3]; - float new_depth; - float screen_loc[2]; - float new_dist; - - copy_v3_v3(location, vco); - - mul_m4_v3(obmat, location); - - new_depth = len_v3v3(location, ray_start); - - if (ED_view3d_project_float_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { - new_dist = len_manhattan_v2v2(mval_fl, screen_loc); - } - else { - new_dist = TRANSFORM_DIST_MAX_PX; - } - - - if (new_dist <= *r_dist_px && new_depth < *ray_depth) { - *ray_depth = new_depth; - retval = true; - - copy_v3_v3(r_loc, location); - - if (r_no) { - normal_short_to_float_v3(r_no, vno); - mul_m3_v3(timat, r_no); - normalize_v3(r_no); - } - - *r_dist_px = new_dist; - } - } - - return retval; -} - -static bool snapArmature( - ARegion *ar, Object *ob, bArmature *arm, float obmat[4][4], - const float mval[2], const short snap_to, - const float ray_start[3], const float ray_normal[3], float *ray_depth, - float r_loc[3], float *UNUSED(r_no), float *r_dist_px) -{ - float imat[4][4]; - float ray_start_local[3], ray_normal_local[3]; - bool retval = false; - - invert_m4_m4(imat, obmat); - - mul_v3_m4v3(ray_start_local, imat, ray_start); - mul_v3_mat3_m4v3(ray_normal_local, imat, ray_normal); - - if (arm->edbo) { - EditBone *eBone; - - for (eBone = arm->edbo->first; eBone; eBone = eBone->next) { - if (eBone->layer & arm->layer) { - /* skip hidden or moving (selected) bones */ - if ((eBone->flag & (BONE_HIDDEN_A | BONE_ROOTSEL | BONE_TIPSEL)) == 0) { - switch (snap_to) { - case SCE_SNAP_MODE_VERTEX: - retval |= snapVertex(ar, eBone->head, NULL, obmat, NULL, mval, ray_start, ray_start_local, ray_normal_local, ray_depth, r_loc, NULL, r_dist_px); - retval |= snapVertex(ar, eBone->tail, NULL, obmat, NULL, mval, ray_start, ray_start_local, ray_normal_local, ray_depth, r_loc, NULL, r_dist_px); - break; - case SCE_SNAP_MODE_EDGE: - retval |= snapEdge(ar, eBone->head, NULL, eBone->tail, NULL, obmat, NULL, mval, ray_start, ray_start_local, ray_normal_local, ray_depth, r_loc, NULL, r_dist_px); - break; - } - } - } - } - } - else if (ob->pose && ob->pose->chanbase.first) { - bPoseChannel *pchan; - Bone *bone; - - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - bone = pchan->bone; - /* skip hidden bones */ - if (bone && !(bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) { - const float *head_vec = pchan->pose_head; - const float *tail_vec = pchan->pose_tail; - - switch (snap_to) { - case SCE_SNAP_MODE_VERTEX: - retval |= snapVertex(ar, head_vec, NULL, obmat, NULL, mval, ray_start, ray_start_local, ray_normal_local, ray_depth, r_loc, NULL, r_dist_px); - retval |= snapVertex(ar, tail_vec, NULL, obmat, NULL, mval, ray_start, ray_start_local, ray_normal_local, ray_depth, r_loc, NULL, r_dist_px); - break; - case SCE_SNAP_MODE_EDGE: - retval |= snapEdge(ar, head_vec, NULL, tail_vec, NULL, obmat, NULL, mval, ray_start, ray_start_local, ray_normal_local, ray_depth, r_loc, NULL, r_dist_px); - break; - } - } - } - } - - return retval; -} - -static bool snapCurve( - ARegion *ar, Object *ob, Curve *cu, float obmat[4][4], - const float mval[2], const short snap_to, - const float ray_start[3], const float ray_normal[3], float *ray_depth, - float r_loc[3], float *UNUSED(r_no), float *r_dist_px) -{ - float imat[4][4]; - float ray_start_local[3], ray_normal_local[3]; - bool retval = false; - int u; - - Nurb *nu; - - /* only vertex snapping mode (eg control points and handles) supported for now) */ - if (snap_to != SCE_SNAP_MODE_VERTEX) { - return retval; - } - - invert_m4_m4(imat, obmat); - - copy_v3_v3(ray_start_local, ray_start); - copy_v3_v3(ray_normal_local, ray_normal); - - mul_m4_v3(imat, ray_start_local); - mul_mat3_m4_v3(imat, ray_normal_local); - - for (nu = (ob->mode == OB_MODE_EDIT ? cu->editnurb->nurbs.first : cu->nurb.first); nu; nu = nu->next) { - for (u = 0; u < nu->pntsu; u++) { - switch (snap_to) { - case SCE_SNAP_MODE_VERTEX: - { - if (ob->mode == OB_MODE_EDIT) { - if (nu->bezt) { - /* don't snap to selected (moving) or hidden */ - if (nu->bezt[u].f2 & SELECT || nu->bezt[u].hide != 0) { - break; - } - retval |= snapVertex(ar, nu->bezt[u].vec[1], NULL, obmat, NULL, mval, ray_start, ray_start_local, ray_normal_local, ray_depth, r_loc, NULL, r_dist_px); - /* don't snap if handle is selected (moving), or if it is aligning to a moving handle */ - if (!(nu->bezt[u].f1 & SELECT) && !(nu->bezt[u].h1 & HD_ALIGN && nu->bezt[u].f3 & SELECT)) { - retval |= snapVertex(ar, nu->bezt[u].vec[0], NULL, obmat, NULL, mval, ray_start, ray_start_local, ray_normal_local, ray_depth, r_loc, NULL, r_dist_px); - } - if (!(nu->bezt[u].f3 & SELECT) && !(nu->bezt[u].h2 & HD_ALIGN && nu->bezt[u].f1 & SELECT)) { - retval |= snapVertex(ar, nu->bezt[u].vec[2], NULL, obmat, NULL, mval, ray_start, ray_start_local, ray_normal_local, ray_depth, r_loc, NULL, r_dist_px); - } - } - else { - /* don't snap to selected (moving) or hidden */ - if (nu->bp[u].f1 & SELECT || nu->bp[u].hide != 0) { - break; - } - retval |= snapVertex(ar, nu->bp[u].vec, NULL, obmat, NULL, mval, ray_start, ray_start_local, ray_normal_local, ray_depth, r_loc, NULL, r_dist_px); - } - } - else { - /* curve is not visible outside editmode if nurb length less than two */ - if (nu->pntsu > 1) { - if (nu->bezt) { - retval |= snapVertex(ar, nu->bezt[u].vec[1], NULL, obmat, NULL, mval, ray_start, ray_start_local, ray_normal_local, ray_depth, r_loc, NULL, r_dist_px); - } - else { - retval |= snapVertex(ar, nu->bp[u].vec, NULL, obmat, NULL, mval, ray_start, ray_start_local, ray_normal_local, ray_depth, r_loc, NULL, r_dist_px); - } - } - } - break; - } - default: - break; - } - } - } - return retval; -} - -static int dm_looptri_to_poly_index(DerivedMesh *dm, const MLoopTri *lt) -{ - const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); - return index_mp_to_orig ? index_mp_to_orig[lt->poly] : lt->poly; -} - -static bool snapDerivedMesh( - ARegion *ar, Object *ob, DerivedMesh *dm, BMEditMesh *em, float obmat[4][4], - const float mval[2], const short snap_to, bool do_bb, - const float ray_start[3], const float ray_normal[3], const float ray_origin[3], float *ray_depth, - float r_loc[3], float r_no[3], float *r_dist_px, int *r_index) -{ - bool retval = false; - int totvert = dm->getNumVerts(dm); - - if (totvert > 0) { - const bool do_ray_start_correction = ( - ELEM(snap_to, SCE_SNAP_MODE_FACE, SCE_SNAP_MODE_VERTEX) && - (ar && !((RegionView3D *)ar->regiondata)->is_persp)); - bool need_ray_start_correction_init = do_ray_start_correction; - - float imat[4][4]; - float timat[3][3]; /* transpose inverse matrix for normals */ - float ray_start_local[3], ray_normal_local[3]; - float local_scale, local_depth, len_diff; - - BVHTreeFromMesh treedata = {0}; - - invert_m4_m4(imat, obmat); - transpose_m3_m4(timat, imat); - - copy_v3_v3(ray_start_local, ray_start); - copy_v3_v3(ray_normal_local, ray_normal); - - mul_m4_v3(imat, ray_start_local); - mul_mat3_m4_v3(imat, ray_normal_local); - - /* local scale in normal direction */ - local_scale = normalize_v3(ray_normal_local); - local_depth = *ray_depth; - if (local_depth != BVH_RAYCAST_DIST_MAX) { - local_depth *= local_scale; - } - - if (do_bb) { - BoundBox *bb = BKE_object_boundbox_get(ob); - - if (bb) { - BoundBox bb_temp; - - /* We cannot aford a bbox with some null dimension, which may happen in some cases... - * Threshold is rather high, but seems to be needed to get good behavior, see T46099. */ - bb = BKE_boundbox_ensure_minimum_dimensions(bb, &bb_temp, 1e-1f); - - /* Exact value here is arbitrary (ideally we would scale in pixel-space based on 'r_dist_px'), - * scale up so we can snap against verts & edges on the boundbox, see T46816. */ - if (ELEM(snap_to, SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE)) { - BKE_boundbox_scale(&bb_temp, bb, 1.0f + 1e-1f); - bb = &bb_temp; - } - - /* was local_depth, see: T47838 */ - len_diff = BVH_RAYCAST_DIST_MAX; - - if (!BKE_boundbox_ray_hit_check(bb, ray_start_local, ray_normal_local, &len_diff)) { - return retval; - } - need_ray_start_correction_init = false; - } - } - - treedata.em_evil = em; - treedata.em_evil_all = false; - switch (snap_to) { - case SCE_SNAP_MODE_FACE: - bvhtree_from_mesh_looptri(&treedata, dm, 0.0f, 4, 6); - break; - case SCE_SNAP_MODE_VERTEX: - bvhtree_from_mesh_verts(&treedata, dm, 0.0f, 2, 6); - break; - } - - if (need_ray_start_correction_init) { - /* We *need* a reasonably valid len_diff in this case. - * Use BHVTree to find the closest face from ray_start_local. - */ - BVHTreeNearest nearest; - - if (treedata.tree != NULL) { - nearest.index = -1; - nearest.dist_sq = FLT_MAX; - /* Compute and store result. */ - BLI_bvhtree_find_nearest( - treedata.tree, ray_start_local, &nearest, treedata.nearest_callback, &treedata); - if (nearest.index != -1) { - len_diff = sqrtf(nearest.dist_sq); - } - } - } - /* 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). - * Note also ar might be null (see T38435), in this case we assume ray_start is ok! - */ - if (do_ray_start_correction) { - float ray_org_local[3]; - - copy_v3_v3(ray_org_local, ray_origin); - mul_m4_v3(imat, ray_org_local); - - /* We pass a temp ray_start, set from object's boundbox, to avoid precision issues with very far - * away ray_start values (as returned in case of ortho view3d), see T38358. - */ - len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */ - madd_v3_v3v3fl(ray_start_local, ray_org_local, ray_normal_local, - len_diff - len_v3v3(ray_start_local, ray_org_local)); - local_depth -= len_diff; - } - else { - len_diff = 0.0f; - } - - switch (snap_to) { - case SCE_SNAP_MODE_FACE: - { - BVHTreeRayHit hit; - - hit.index = -1; - hit.dist = local_depth; - - if (treedata.tree && - BLI_bvhtree_ray_cast(treedata.tree, ray_start_local, ray_normal_local, 0.0f, - &hit, treedata.raycast_callback, &treedata) != -1) - { - hit.dist += len_diff; - hit.dist /= local_scale; - if (hit.dist <= *ray_depth) { - *ray_depth = hit.dist; - copy_v3_v3(r_loc, hit.co); - copy_v3_v3(r_no, hit.no); - - /* back to worldspace */ - mul_m4_v3(obmat, r_loc); - mul_m3_v3(timat, r_no); - normalize_v3(r_no); - - retval = true; - - if (r_index) { - *r_index = dm_looptri_to_poly_index(dm, &treedata.looptri[hit.index]); - } - } - } - break; - } - case SCE_SNAP_MODE_VERTEX: - { - BVHTreeNearest nearest; - - nearest.index = -1; - nearest.dist_sq = local_depth * local_depth; - if (treedata.tree && - BLI_bvhtree_find_nearest_to_ray( - treedata.tree, ray_start_local, ray_normal_local, - &nearest, NULL, NULL) != -1) - { - const MVert *v = &treedata.vert[nearest.index]; - retval = snapVertex( - ar, v->co, v->no, obmat, timat, mval, - ray_start, ray_start_local, ray_normal_local, ray_depth, - r_loc, r_no, r_dist_px); - } - break; - } - case SCE_SNAP_MODE_EDGE: - { - MVert *verts = dm->getVertArray(dm); - MEdge *edges = dm->getEdgeArray(dm); - int totedge = dm->getNumEdges(dm); - const int *index_array = NULL; - int index = 0; - int i; - - if (em != NULL) { - index_array = dm->getEdgeDataArray(dm, CD_ORIGINDEX); - BM_mesh_elem_table_ensure(em->bm, BM_EDGE); - } - - for (i = 0; i < totedge; i++) { - MEdge *e = edges + i; - bool test = true; - - if (em != NULL) { - if (index_array) { - index = index_array[i]; - } - else { - index = i; - } - - if (index == ORIGINDEX_NONE) { - test = false; - } - else { - BMEdge *eed = BM_edge_at_index(em->bm, index); - - if (BM_elem_flag_test(eed, BM_ELEM_HIDDEN) || - BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) || - BM_elem_flag_test(eed->v2, BM_ELEM_SELECT)) - { - test = false; - } - } - } - - if (test) { - retval |= snapEdge( - ar, verts[e->v1].co, verts[e->v1].no, verts[e->v2].co, verts[e->v2].no, obmat, timat, - mval, ray_start, ray_start_local, ray_normal_local, ray_depth, - r_loc, r_no, r_dist_px); - } - } - - break; - } - } - - free_bvhtree_from_mesh(&treedata); - } - - return retval; -} - -/* may extend later (for now just snaps to empty center) */ -static bool snapEmpty( - ARegion *ar, Object *ob, float obmat[4][4], - const float mval[2], const short snap_to, - const float ray_start[3], const float ray_normal[3], float *ray_depth, - float r_loc[3], float *UNUSED(r_no), float *r_dist_px) -{ - float imat[4][4]; - float ray_start_local[3], ray_normal_local[3]; - bool retval = false; - - if (ob->transflag & OB_DUPLI) { - return retval; - } - /* for now only vertex supported */ - if (snap_to != SCE_SNAP_MODE_VERTEX) { - return retval; - } - - invert_m4_m4(imat, obmat); - - mul_v3_m4v3(ray_start_local, imat, ray_start); - mul_v3_mat3_m4v3(ray_normal_local, imat, ray_normal); - - switch (snap_to) { - case SCE_SNAP_MODE_VERTEX: - { - const float zero_co[3] = {0.0f}; - retval |= snapVertex( - ar, zero_co, NULL, obmat, NULL, mval, - ray_start, ray_start_local, ray_normal_local, ray_depth, - r_loc, NULL, r_dist_px); - break; - } - default: - break; - } - - return retval; -} - -static bool snapCamera( - ARegion *ar, Scene *scene, Object *object, float obmat[4][4], - const float mval[2], const short snap_to, - const float ray_start[3], const float ray_normal[3], float *ray_depth, - float r_loc[3], float *UNUSED(r_no), float *r_dist_px) -{ - float orig_camera_mat[4][4], orig_camera_imat[4][4], imat[4][4]; - bool retval = false; - MovieClip *clip = BKE_object_movieclip_get(scene, object, false); - MovieTracking *tracking; - float ray_start_local[3], ray_normal_local[3]; - - if (clip == NULL) { - return retval; - } - if (object->transflag & OB_DUPLI) { - return retval; - } - - tracking = &clip->tracking; - - BKE_tracking_get_camera_object_matrix(scene, object, orig_camera_mat); - - invert_m4_m4(orig_camera_imat, orig_camera_mat); - invert_m4_m4(imat, obmat); - - switch (snap_to) { - case SCE_SNAP_MODE_VERTEX: - { - MovieTrackingObject *tracking_object; - - for (tracking_object = tracking->objects.first; - tracking_object; - tracking_object = tracking_object->next) - { - ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object); - MovieTrackingTrack *track; - float reconstructed_camera_mat[4][4], - reconstructed_camera_imat[4][4]; - float (*vertex_obmat)[4]; - - copy_v3_v3(ray_start_local, ray_start); - copy_v3_v3(ray_normal_local, ray_normal); - - if ((tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0) { - BKE_tracking_camera_get_reconstructed_interpolate(tracking, tracking_object, - CFRA, reconstructed_camera_mat); - - invert_m4_m4(reconstructed_camera_imat, reconstructed_camera_mat); - } - - for (track = tracksbase->first; track; track = track->next) { - float bundle_pos[3]; - - if ((track->flag & TRACK_HAS_BUNDLE) == 0) { - continue; - } - - copy_v3_v3(bundle_pos, track->bundle_pos); - if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { - mul_m4_v3(orig_camera_imat, ray_start_local); - mul_mat3_m4_v3(orig_camera_imat, ray_normal_local); - vertex_obmat = orig_camera_mat; - } - else { - mul_m4_v3(reconstructed_camera_imat, bundle_pos); - mul_m4_v3(imat, ray_start_local); - mul_mat3_m4_v3(imat, ray_normal_local); - vertex_obmat = obmat; - } - - retval |= snapVertex( - ar, bundle_pos, NULL, vertex_obmat, NULL, mval, - ray_start, ray_start_local, ray_normal_local, ray_depth, - r_loc, NULL, r_dist_px); - } - } - - break; - } - default: - break; - } - - return retval; -} - -static bool snapObject( - Scene *scene, ARegion *ar, Object *ob, float obmat[4][4], bool use_obedit, - const float mval[2], const short snap_to, - const float ray_start[3], const float ray_normal[3], const float ray_origin[3], float *ray_depth, - /* return args */ - float r_loc[3], float r_no[3], float *r_dist_px, int *r_index, - Object **r_ob, float r_obmat[4][4]) -{ - bool retval = false; - - if (ob->type == OB_MESH) { - BMEditMesh *em; - DerivedMesh *dm; - bool do_bb = true; - - if (use_obedit) { - em = BKE_editmesh_from_object(ob); - dm = editbmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH); - do_bb = false; - } - else { - /* in this case we want the mesh from the editmesh, avoids stale data. see: T45978. - * still set the 'em' to NULL, since we only want the 'dm'. */ - em = BKE_editmesh_from_object(ob); - if (em) { - editbmesh_get_derived_cage_and_final(scene, ob, em, CD_MASK_BAREMESH, &dm); - } - else { - dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); - } - em = NULL; - } - - retval = snapDerivedMesh( - ar, ob, dm, em, obmat, mval, snap_to, do_bb, - ray_start, ray_normal, ray_origin, ray_depth, - r_loc, r_no, r_dist_px, r_index); - - dm->release(dm); - } - else if (ob->type == OB_ARMATURE) { - retval = snapArmature( - ar, ob, ob->data, obmat, mval, snap_to, - ray_start, ray_normal, ray_depth, - r_loc, r_no, r_dist_px); - } - else if (ob->type == OB_CURVE) { - retval = snapCurve( - ar, ob, ob->data, obmat, mval, snap_to, - ray_start, ray_normal, ray_depth, - r_loc, r_no, r_dist_px); - } - else if (ob->type == OB_EMPTY) { - retval = snapEmpty( - ar, ob, obmat, mval, snap_to, - ray_start, ray_normal, ray_depth, - r_loc, r_no, r_dist_px); - } - else if (ob->type == OB_CAMERA) { - retval = snapCamera( - ar, scene, ob, obmat, mval, snap_to, - ray_start, ray_normal, ray_depth, - r_loc, r_no, r_dist_px); - } - - if (retval) { - if (r_ob) { - *r_ob = ob; - copy_m4_m4(r_obmat, obmat); - } - } - - return retval; -} - -static bool snapObjectsRay( - Scene *scene, View3D *v3d, ARegion *ar, Base *base_act, Object *obedit, - const float mval[2], SnapSelect snap_select, const short snap_to, - const float ray_start[3], const float ray_normal[3], const float ray_origin[3], float *ray_depth, - /* return args */ - float r_loc[3], float r_no[3], float *r_dist_px, int *r_index, - Object **r_ob, float r_obmat[4][4]) -{ - Base *base; - bool retval = false; - - if (snap_select == SNAP_ALL && obedit) { - Object *ob = obedit; - - retval |= snapObject( - scene, ar, ob, ob->obmat, true, - mval, snap_to, - ray_start, ray_normal, ray_origin, ray_depth, - r_loc, r_no, r_dist_px, r_index, r_ob, r_obmat); - } - - /* Need an exception for particle edit because the base is flagged with BA_HAS_RECALC_DATA - * which makes the loop skip it, even the derived mesh will never change - * - * To solve that problem, we do it first as an exception. - * */ - base = base_act; - if (base && base->object && base->object->mode & OB_MODE_PARTICLE_EDIT) { - Object *ob = base->object; - retval |= snapObject( - scene, ar, ob, ob->obmat, false, - mval, snap_to, - ray_start, ray_normal, ray_origin, ray_depth, - r_loc, r_no, r_dist_px, r_index, r_ob, r_obmat); - } - - for (base = FIRSTBASE; base != NULL; base = base->next) { - if ((BASE_VISIBLE_BGMODE(v3d, scene, base)) && - (base->flag & (BA_HAS_RECALC_OB | BA_HAS_RECALC_DATA)) == 0 && - - ((snap_select == SNAP_NOT_SELECTED && (base->flag & (SELECT | BA_WAS_SEL)) == 0) || - (ELEM(snap_select, SNAP_ALL, SNAP_NOT_OBEDIT) && base != base_act))) - { - Object *ob = base->object; - Object *ob_snap = ob; - bool use_obedit = false; - - /* for linked objects, use the same object but a different matrix */ - if (obedit && ob->data == obedit->data) { - use_obedit = true; - ob_snap = obedit; - } - - if (ob->transflag & OB_DUPLI) { - DupliObject *dupli_ob; - ListBase *lb = object_duplilist(G.main->eval_ctx, scene, ob); - - for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { - bool use_obedit_dupli = (obedit && dupli_ob->ob->data == obedit->data); - Object *dupli_snap = (use_obedit_dupli) ? obedit : dupli_ob->ob; - - retval |= snapObject( - scene, ar, dupli_snap, dupli_ob->mat, use_obedit_dupli, - mval, snap_to, - ray_start, ray_normal, ray_origin, ray_depth, - r_loc, r_no, r_dist_px, r_index, r_ob, r_obmat); - } - - free_object_duplilist(lb); - } - - retval |= snapObject( - scene, ar, ob_snap, ob->obmat, use_obedit, - mval, snap_to, - ray_start, ray_normal, ray_origin, ray_depth, - r_loc, r_no, r_dist_px, r_index, r_ob, r_obmat); - } - } - - return retval; -} -static bool snapObjects( - Scene *scene, View3D *v3d, ARegion *ar, Base *base_act, Object *obedit, - const float mval[2], SnapSelect snap_select, const short snap_to, - float *ray_depth, - float r_loc[3], float r_no[3], float *r_dist_px, int *r_index) -{ - float ray_start[3], ray_normal[3], ray_orgigin[3]; - - if (!ED_view3d_win_to_ray_ex(ar, v3d, mval, ray_orgigin, ray_normal, ray_start, true)) { - return false; - } - - return snapObjectsRay( - scene, v3d, ar, base_act, obedit, - mval, snap_select, snap_to, - ray_start, ray_normal, ray_orgigin, ray_depth, - r_loc, r_no, r_dist_px, r_index, NULL, NULL); -} - bool snapObjectsTransform( TransInfo *t, const float mval[2], SnapSelect snap_select, - float r_loc[3], float r_no[3], float *r_dist_px) + float *dist_px, + float r_loc[3], float r_no[3]) { float ray_dist = BVH_RAYCAST_DIST_MAX; - Object *obedit = NULL; - Base *base_act = NULL; - if (t->flag & T_EDIT) { - obedit = t->obedit; - } - - if ((t->options & CTX_GPENCIL_STROKES) == 0) { - base_act = t->scene->basact; - } - - return snapObjects( - t->scene, t->view, t->ar, base_act, obedit, - mval, snap_select, t->scene->toolsettings->snap_mode, - &ray_dist, - r_loc, r_no, r_dist_px, NULL); -} - -bool snapObjectsContext( - bContext *C, const float mval[2], SnapSelect snap_select, - float r_loc[3], float r_no[3], float *r_dist_px) -{ - ScrArea *sa = CTX_wm_area(C); - View3D *v3d = sa->spacedata.first; - Scene *scene = CTX_data_scene(C); - ARegion *ar = CTX_wm_region(C); - Object *obedit = CTX_data_edit_object(C); - float ray_dist = BVH_RAYCAST_DIST_MAX; - - return snapObjects( - scene, v3d, ar, scene->basact, obedit, - mval, snap_select, scene->toolsettings->snap_mode, + return ED_transform_snap_object_project_view3d_ex( + t->tsnap.object_context, + &(const struct SnapObjectParams){ + .snap_select = snap_select, + .snap_to = t->scene->toolsettings->snap_mode, + .use_object_edit = (t->flag & T_EDIT) != 0, + .use_object_active = (t->options & CTX_GPENCIL_STROKES) == 0, + }, + mval, dist_px, &ray_dist, - r_loc, r_no, r_dist_px, NULL); + r_loc, r_no, NULL); } -bool snapObjectsEx( - Scene *scene, View3D *v3d, ARegion *ar, Base *base_act, Object *obedit, - const float mval[2], SnapSelect snap_select, const short snap_to, - float *ray_depth, - float r_loc[3], float r_no[3], float *r_dist_px) -{ - return snapObjects( - scene, v3d, ar, base_act, obedit, - mval, snap_select, snap_to, - ray_depth, - r_loc, r_no, r_dist_px, NULL); -} -bool snapObjectsRayEx( - Scene *scene, View3D *v3d, ARegion *ar, Base *base_act, Object *obedit, - const float mval[2], SnapSelect snap_select, const short snap_to, - const float ray_start[3], const float ray_normal[3], float *ray_depth, - float r_loc[3], float r_no[3], float *r_dist_px, int *r_index, - Object **r_ob, float r_obmat[4][4]) -{ - return snapObjectsRay( - scene, v3d, ar, base_act, obedit, - mval, snap_select, snap_to, - ray_start, ray_normal, ray_start, ray_depth, - r_loc, r_no, r_dist_px, r_index, - r_ob, r_obmat); -} /******************** PEELING *********************************/ |