transform_snap_object: Use the texture space bound box to test the need to snap to meshes in edit mode.

Before a value for bound box was stored in a local cache.
This commit is contained in:
2018-11-21 14:37:56 -02:00
parent 2261aed031
commit 2ab798feb0
3 changed files with 71 additions and 99 deletions

View File

@@ -165,7 +165,7 @@ void BKE_mesh_smooth_flag_set(struct Object *meshOb, int enableSmooth);
const char *BKE_mesh_cmp(struct Mesh *me1, struct Mesh *me2, float thresh);
struct BoundBox *BKE_mesh_boundbox_get(struct Object *ob);
void BKE_mesh_texspace_get(struct Mesh *me, float r_loc[3], float r_rot[3], float r_size[3]);
struct BoundBox *BKE_mesh_texspace_get(struct Mesh *me, float r_loc[3], float r_rot[3], float r_size[3]);
void BKE_mesh_texspace_get_reference(struct Mesh *me, short **r_texflag, float **r_loc, float **r_rot, float **r_size);
void BKE_mesh_texspace_copy_from_object(struct Mesh *me, struct Object *ob);

View File

@@ -926,7 +926,7 @@ BoundBox *BKE_mesh_boundbox_get(Object *ob)
return me->bb;
}
void BKE_mesh_texspace_get(Mesh *me, float r_loc[3], float r_rot[3], float r_size[3])
BoundBox *BKE_mesh_texspace_get(Mesh *me, float r_loc[3], float r_rot[3], float r_size[3])
{
if (me->bb == NULL || (me->bb->flag & BOUNDBOX_DIRTY)) {
BKE_mesh_texspace_calc(me);
@@ -935,6 +935,8 @@ void BKE_mesh_texspace_get(Mesh *me, float r_loc[3], float r_rot[3], float r_siz
if (r_loc) copy_v3_v3(r_loc, me->loc);
if (r_rot) copy_v3_v3(r_rot, me->rot);
if (r_size) copy_v3_v3(r_size, me->size);
return me->bb;
}
void BKE_mesh_texspace_get_reference(Mesh *me, short **r_texflag, float **r_loc, float **r_rot, float **r_size)

View File

@@ -112,10 +112,6 @@ typedef struct SnapObjectData_EditMesh {
SnapObjectData sd;
BVHTreeFromEditMesh *bvh_trees[3];
/* It's like a boundbox. It is tested first to avoid
* to create a bvhtree for all the edited objects. */
float min[3], max[3];
} SnapObjectData_EditMesh;
struct SnapObjectContext {
@@ -161,18 +157,6 @@ struct SnapObjectContext {
typedef void(*IterSnapObjsCallback)(SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data);
static void min_max_from_bmesh(
BMesh *bm, float r_min[3], float r_max[3])
{
BMIter iter;
BMVert *eve;
INIT_MINMAX(r_min, r_max);
BM_ITER_MESH(eve, &iter, bm, BM_VERTS_OF_MESH) {
minmax_v3v3_v3(r_min, r_max, eve->co);
}
}
static SnapObjectData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx, Object *ob)
{
void **sod_p;
@@ -202,7 +186,6 @@ static SnapObjectData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext
else {
SnapObjectData_EditMesh *sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
sod->sd.type = SNAP_EDIT_MESH;
min_max_from_bmesh(em->bm, sod->min, sod->max);
}
return *sod_p;
@@ -383,12 +366,10 @@ static bool raycastMesh(
}
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 = 0.0f;
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_dir);
@@ -478,6 +459,10 @@ static bool raycastMesh(
else {
len_diff = 0.0f;
}
float timat[3][3]; /* transpose inverse matrix for normals */
transpose_m3_m4(timat, imat);
if (r_hit_list) {
struct RayCastAll_Data data;
@@ -549,19 +534,38 @@ static bool raycastEditMesh(
BLI_assert(em->ob->data == BKE_object_get_pre_modified_mesh(ob));
SnapObjectData_EditMesh *sod = snap_object_data_editmesh_get(sctx, em);
{
float min[3], max[3];
mul_v3_m4v3(min, obmat, sod->min);
mul_v3_m4v3(max, obmat, sod->max);
float imat[4][4];
float ray_start_local[3], ray_normal_local[3];
float local_scale, local_depth, len_diff = 0.0f;
invert_m4_m4(imat, obmat);
copy_v3_v3(ray_start_local, ray_start);
copy_v3_v3(ray_normal_local, ray_dir);
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;
}
/* Test BoundBox */
BoundBox *bb = BKE_mesh_texspace_get(em->ob->data, NULL, NULL, NULL);
if (bb) {
/* was BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */
if (!isect_ray_aabb_v3_simple(
ray_start, ray_dir, min, max, NULL, NULL))
ray_start_local, ray_normal_local, bb->vec[0], bb->vec[6], &len_diff, NULL))
{
return retval;
}
}
SnapObjectData_EditMesh *sod = snap_object_data_editmesh_get(sctx, em);
if (sod->bvh_trees[2] == NULL) {
sod->bvh_trees[2] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(BVHTreeFromEditMesh));
}
@@ -610,26 +614,6 @@ static bool raycastEditMesh(
treedata->em = em;
}
float imat[4][4];
float timat[3][3]; /* transpose inverse matrix for normals */
float ray_normal_local[3], ray_start_local[3], len_diff = 0.0f;
invert_m4_m4(imat, obmat);
transpose_m3_m4(timat, imat);
copy_v3_v3(ray_normal_local, ray_dir);
mul_mat3_m4_v3(imat, ray_normal_local);
copy_v3_v3(ray_start_local, ray_start);
mul_m4_v3(imat, ray_start_local);
/* local scale in normal direction */
float local_scale = normalize_v3(ray_normal_local);
float local_depth = *ray_depth;
if (local_depth != BVH_RAYCAST_DIST_MAX) {
local_depth *= local_scale;
}
/* 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!
@@ -653,6 +637,10 @@ static bool raycastEditMesh(
}
else len_diff = 0.0f;
}
float timat[3][3]; /* transpose inverse matrix for normals */
transpose_m3_m4(timat, imat);
if (r_hit_list) {
struct RayCastAll_Data data;
@@ -875,6 +863,25 @@ static bool raycastObjects(
/** Snap Nearest utilities
* \{ */
/* Test BoundBox */
bool snap_bound_box_check_dist(BoundBox *bb, float lpmat[4][4], float win_size[2], float mval[2], float dist_px_sq)
{
/* In vertex and edges you need to get the pixel distance from ray to BoundBox, see: T46099, T46816 */
struct DistProjectedAABBPrecalc data_precalc;
dist_squared_to_projected_aabb_precalc(
&data_precalc, lpmat, win_size, mval);
bool dummy[3];
float bb_dist_px_sq = dist_squared_to_projected_aabb(
&data_precalc, bb->vec[0], bb->vec[6], dummy);
if (bb_dist_px_sq > dist_px_sq) {
return false;
}
return true;
}
static void cb_mvert_co_get(
const int index, const float **co, const BVHTreeFromMesh *data)
{
@@ -1421,17 +1428,10 @@ static short snapArmature(
if (use_obedit == false) {
/* Test BoundBox */
BoundBox *bb = BKE_armature_boundbox_get(ob);
if (bb) {
bool dummy[3];
/* In vertex and edges you need to get the pixel distance from ray to BoundBox, see: T46099, T46816 */
float bb_dist_px_sq = dist_squared_to_projected_aabb(
&neasrest_precalc, bb->vec[0], bb->vec[6], dummy);
if (bb_dist_px_sq > dist_px_sq) {
if (bb && !snap_bound_box_check_dist(bb, lpmat, snapdata->win_size, snapdata->mval, dist_px_sq)) {
return retval;
}
}
}
float tobmat[4][4], clip_planes_local[MAX_CLIPPLANE_LEN][4];
transpose_m4_m4(tobmat, obmat);
@@ -1557,17 +1557,10 @@ static short snapCurve(
if (use_obedit == false) {
/* Test BoundBox */
BoundBox *bb = BKE_curve_texspace_get(cu, NULL, NULL, NULL);
if (bb) {
bool dummy[3];
/* In vertex and edges you need to get the pixel distance from ray to BoundBox, see: T46099, T46816 */
float bb_dist_px_sq = dist_squared_to_projected_aabb(
&neasrest_precalc, bb->vec[0], bb->vec[6], dummy);
if (bb_dist_px_sq > dist_px_sq) {
if (bb && !snap_bound_box_check_dist(bb, lpmat, snapdata->win_size, snapdata->mval, dist_px_sq)) {
return 0;
}
}
}
float tobmat[4][4], clip_planes_local[MAX_CLIPPLANE_LEN][4];
transpose_m4_m4(tobmat, obmat);
@@ -1841,21 +1834,9 @@ static short snapMesh(
/* Test BoundBox */
BoundBox *bb = BKE_mesh_boundbox_get(ob);
if (bb) {
/* In vertex and edges you need to get the pixel distance from ray to BoundBox, see: T46099, T46816 */
struct DistProjectedAABBPrecalc data_precalc;
dist_squared_to_projected_aabb_precalc(
&data_precalc, lpmat, snapdata->win_size, snapdata->mval);
bool dummy[3];
float bb_dist_px_sq = dist_squared_to_projected_aabb(
&data_precalc, bb->vec[0], bb->vec[6], dummy);
if (bb_dist_px_sq > dist_px_sq) {
if (bb && !snap_bound_box_check_dist(bb, lpmat, snapdata->win_size, snapdata->mval, dist_px_sq)) {
return 0;
}
}
SnapObjectData_Mesh *sod = snap_object_data_mesh_get(sctx, ob);
@@ -2057,28 +2038,18 @@ static short snapEditMesh(
BLI_assert(em->ob->data == BKE_object_get_pre_modified_mesh(ob));
UNUSED_VARS_NDEBUG(ob);
SnapObjectData_EditMesh *sod = snap_object_data_editmesh_get(sctx, em);
float lpmat[4][4];
mul_m4_m4m4(lpmat, snapdata->pmat, obmat);
float dist_px_sq = SQUARE(*dist_px);
{
float min[3], max[3];
mul_v3_m4v3(min, obmat, sod->min);
mul_v3_m4v3(max, obmat, sod->max);
/* In vertex and edges you need to get the pixel distance from ray to BoundBox, see: T46099, T46816 */
struct DistProjectedAABBPrecalc data_precalc;
dist_squared_to_projected_aabb_precalc(
&data_precalc, snapdata->pmat, snapdata->win_size, snapdata->mval);
bool dummy[3];
float bb_dist_px_sq = dist_squared_to_projected_aabb(
&data_precalc, min, max, dummy);
if (bb_dist_px_sq > dist_px_sq) {
/* Test BoundBox */
BoundBox *bb = BKE_mesh_texspace_get(em->ob->data, NULL, NULL, NULL);
if (bb && !snap_bound_box_check_dist(bb, lpmat, snapdata->win_size, snapdata->mval, dist_px_sq)) {
return 0;
}
}
SnapObjectData_EditMesh *sod = snap_object_data_editmesh_get(sctx, em);
BVHCache *em_bvh_cache = ((Mesh *)em->ob->data)->runtime.bvh_cache;
@@ -2161,8 +2132,7 @@ static short snapEditMesh(
int last_index = nearest.index;
short elem = SCE_SNAP_MODE_VERTEX;
float lpmat[4][4], tobmat[4][4], clip_planes_local[MAX_CLIPPLANE_LEN][4];
mul_m4_m4m4(lpmat, snapdata->pmat, obmat);
float tobmat[4][4], clip_planes_local[MAX_CLIPPLANE_LEN][4];
transpose_m4_m4(tobmat, obmat);
for (int i = snapdata->clip_plane_len; i--;) {