Transform Snap: Deduplicate code that register the result

The `Nearest2dUserData` object is called in all cases, so move the
registration to its destructor.
This commit is contained in:
Germano Cavalcante
2023-06-21 17:02:05 -03:00
parent 3bbd99e1cb
commit 9ec127bb70
7 changed files with 95 additions and 155 deletions

View File

@@ -97,7 +97,8 @@ static bool test_projected_edge_dist(const DistProjectedAABBPrecalc *precalc,
}
Nearest2dUserData::Nearest2dUserData(SnapObjectContext *sctx,
float dist_px_sq,
Object *ob_eval,
const ID *id_eval,
const float4x4 &obmat)
: get_vert_co(nullptr),
get_edge_verts_index(nullptr),
@@ -106,7 +107,13 @@ Nearest2dUserData::Nearest2dUserData(SnapObjectContext *sctx,
copy_vert_no(nullptr),
bm(nullptr),
is_persp(sctx->runtime.rv3d ? sctx->runtime.rv3d->is_persp : false),
use_backface_culling(sctx->runtime.params.use_backface_culling)
use_backface_culling(sctx->runtime.params.use_backface_culling),
/* To register the result. */
sctx_(sctx),
ob_(ob_eval),
id_(id_eval),
obmat_(obmat)
{
if (sctx->runtime.rv3d) {
this->pmat_local = float4x4(sctx->runtime.rv3d->persmat) * obmat;
@@ -119,13 +126,11 @@ Nearest2dUserData::Nearest2dUserData(SnapObjectContext *sctx,
&this->nearest_precalc, this->pmat_local.ptr(), sctx->runtime.win_size, sctx->runtime.mval);
this->nearest_point.index = -2;
this->nearest_point.dist_sq = dist_px_sq;
this->nearest_point.dist_sq = sctx->ret.dist_px_sq;
copy_v3_fl3(this->nearest_point.no, 0.0f, 0.0f, 1.0f);
}
void Nearest2dUserData::clip_planes_get(SnapObjectContext *sctx,
const float4x4 &obmat,
bool skip_occlusion_plane)
void Nearest2dUserData::clip_planes_get(SnapObjectContext *sctx, bool skip_occlusion_plane)
{
float(*clip_planes)[4] = sctx->runtime.clip_plane;
int clip_plane_len = sctx->runtime.clip_plane_len;
@@ -136,7 +141,7 @@ void Nearest2dUserData::clip_planes_get(SnapObjectContext *sctx,
clip_plane_len--;
}
float4x4 tobmat = math::transpose(obmat);
float4x4 tobmat = math::transpose(this->obmat_);
for (int i : IndexRange(clip_plane_len)) {
this->clip_planes.append(tobmat * clip_planes[i]);
}
@@ -201,6 +206,29 @@ bool Nearest2dUserData::snap_edge(const float3 &va, const float3 &vb, int edge_i
return false;
}
Nearest2dUserData::~Nearest2dUserData()
{
if (this->nearest_point.index == -2) {
return;
}
SnapObjectContext *sctx = this->sctx_;
copy_v3_v3(sctx->ret.loc, this->nearest_point.co);
copy_v3_v3(sctx->ret.no, this->nearest_point.no);
sctx->ret.index = this->nearest_point.index;
copy_m4_m4(sctx->ret.obmat, this->obmat_.ptr());
sctx->ret.ob = this->ob_;
sctx->ret.data = this->id_;
sctx->ret.dist_px_sq = this->nearest_point.dist_sq;
mul_m4_v3(this->obmat_.ptr(), sctx->ret.loc);
float3x3 timat = math::transpose(math::invert(float3x3(this->obmat_)));
copy_v3_v3(sctx->ret.no, math::transform_direction(timat, float3(sctx->ret.no)));
normalize_v3(sctx->ret.no);
}
/* -------------------------------------------------------------------- */
/** \name Utilities
* \{ */
@@ -745,7 +773,9 @@ static eSnapMode snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, float origi
return SCE_SNAP_MODE_NONE;
}
Nearest2dUserData nearest2d(sctx, square_f(original_dist_px), float4x4(sctx->ret.obmat));
Nearest2dUserData nearest2d(sctx, sctx->ret.ob, sctx->ret.data, float4x4(sctx->ret.obmat));
nearest2d.nearest_point.dist_sq = square_f(original_dist_px);
if (sctx->ret.data) {
const Mesh *mesh = reinterpret_cast<const Mesh *>(sctx->ret.data);
nearest2d_data_init_mesh(mesh, &nearest2d);
@@ -789,6 +819,7 @@ static eSnapMode snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, float origi
mid_v3_v3v3(vmid, v_pair[0], v_pair[1]);
if (nearest2d.snap_point(vmid, sctx->ret.index)) {
sub_v3_v3v3(nearest2d.nearest_point.no, v_pair[1], v_pair[0]);
elem = SCE_SNAP_MODE_EDGE_MIDPOINT;
}
}
@@ -805,6 +836,7 @@ static eSnapMode snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, float origi
interp_v3_v3v3(v_near, v_pair[0], v_pair[1], lambda_perp);
if (nearest2d.snap_point(v_near, sctx->ret.index)) {
sub_v3_v3v3(nearest2d.nearest_point.no, v_pair[1], v_pair[0]);
elem = SCE_SNAP_MODE_EDGE_PERPENDICULAR;
}
}
@@ -817,22 +849,12 @@ static eSnapMode snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, float origi
if (nearest2d.snap_point(v_pair[v_id], v_id)) {
elem = SCE_SNAP_MODE_VERTEX;
nearest2d.copy_vert_no(vindex[v_id], &nearest2d, sctx->ret.no);
float3x3 timat = math::transpose(math::invert(float3x3(float4x4(sctx->ret.obmat))));
copy_v3_v3(sctx->ret.no, math::transform_direction(timat, float3(sctx->ret.no)));
normalize_v3(sctx->ret.no);
nearest2d.copy_vert_no(vindex[v_id], &nearest2d, nearest2d.nearest_point.no);
}
}
}
}
if (nearest2d.nearest_point.index != -2) {
sctx->ret.dist_px_sq = nearest2d.nearest_point.dist_sq;
mul_v3_m4v3(sctx->ret.loc, sctx->ret.obmat, nearest2d.nearest_point.co);
sctx->ret.index = nearest2d.nearest_point.index;
}
return elem;
}
@@ -842,28 +864,20 @@ eSnapMode snap_object_center(SnapObjectContext *sctx,
const float obmat[4][4],
eSnapMode snap_to_flag)
{
eSnapMode retval = SCE_SNAP_MODE_NONE;
if (ob_eval->transflag & OB_DUPLI) {
return retval;
return SCE_SNAP_MODE_NONE;
}
/* For now only vertex supported. */
if ((snap_to_flag & SCE_SNAP_MODE_VERTEX) == 0) {
return retval;
return SCE_SNAP_MODE_NONE;
}
Nearest2dUserData nearest2d(sctx, sctx->ret.dist_px_sq);
if (nearest2d.snap_point(obmat[3])) {
retval = SCE_SNAP_MODE_VERTEX;
}
Nearest2dUserData nearest2d(
sctx, ob_eval, static_cast<const ID *>(ob_eval->data), float4x4(obmat));
if (retval) {
copy_v3_v3(sctx->ret.loc, nearest2d.nearest_point.co);
sctx->ret.dist_px_sq = nearest2d.nearest_point.dist_sq;
sctx->ret.index = nearest2d.nearest_point.index;
return retval;
if (nearest2d.snap_point(float3(0.0f))) {
return SCE_SNAP_MODE_VERTEX;
}
return SCE_SNAP_MODE_NONE;
@@ -931,12 +945,6 @@ static eSnapMode snap_obj_fn(SnapObjectContext *sctx,
break;
}
}
if (retval) {
copy_m4_m4(sctx->ret.obmat, obmat);
sctx->ret.ob = ob_eval;
sctx->ret.data = ob_data;
}
return retval;
}

View File

@@ -68,7 +68,7 @@ struct SnapObjectContext {
/* Snapped object. */
Object *ob;
/* Snapped data. */
ID *data;
const ID *data;
float ray_depth_max;
float dist_px_sq;
@@ -115,12 +115,11 @@ struct Nearest2dUserData {
public:
/* Constructor. */
Nearest2dUserData(SnapObjectContext *sctx,
float dist_px_sq,
Object *ob_eval,
const ID *id_eval,
const blender::float4x4 &obmat = blender::float4x4::identity());
void clip_planes_get(SnapObjectContext *sctx,
const blender::float4x4 &obmat,
bool skip_occlusion_plane = false);
void clip_planes_get(SnapObjectContext *sctx, bool skip_occlusion_plane = false);
bool snap_boundbox(const blender::float3 &min, const blender::float3 &max);
@@ -156,6 +155,14 @@ struct Nearest2dUserData {
bool use_backface_culling;
BVHTreeNearest nearest_point;
~Nearest2dUserData();
protected:
SnapObjectContext *sctx_;
Object *ob_;
const ID *id_;
const blender::float4x4 &obmat_;
};
/* transform_snap_object.cc */
@@ -235,14 +242,14 @@ struct SnapData_EditMesh {
eSnapMode snap_object_editmesh(SnapObjectContext *sctx,
Object *ob_eval,
ID *id,
const ID *id,
const float obmat[4][4],
eSnapMode snap_to_flag,
bool use_hide);
eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
Object *ob_eval,
ID *id,
const ID *id,
const float obmat[4][4],
eSnapMode snap_to_flag,
int polygon);
@@ -253,14 +260,14 @@ void nearest2d_data_init_editmesh(struct BMEditMesh *em, struct Nearest2dUserDat
eSnapMode snap_object_mesh(SnapObjectContext *sctx,
Object *ob_eval,
ID *id,
const ID *id,
const float obmat[4][4],
eSnapMode snap_to_flag,
bool use_hide);
eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
Object *ob_eval,
ID *id,
const ID *id,
const float obmat[4][4],
eSnapMode snap_to_flag,
int polygon);

View File

@@ -32,9 +32,10 @@ eSnapMode snapArmature(SnapObjectContext *sctx,
return retval;
}
Nearest2dUserData nearest2d(sctx, sctx->ret.dist_px_sq, float4x4(obmat));
bArmature *arm = static_cast<bArmature *>(ob_eval->data);
Nearest2dUserData nearest2d(sctx, ob_eval, &arm->id, float4x4(obmat));
const bool is_editmode = arm->edbo != nullptr;
if (is_editmode == false) {
@@ -44,7 +45,7 @@ eSnapMode snapArmature(SnapObjectContext *sctx,
}
}
nearest2d.clip_planes_get(sctx, float4x4(obmat));
nearest2d.clip_planes_get(sctx);
const bool is_posemode = is_object_active && (ob_eval->mode & OB_MODE_POSE);
const bool skip_selected = (is_editmode || is_posemode) &&
@@ -112,13 +113,5 @@ eSnapMode snapArmature(SnapObjectContext *sctx,
}
}
if (retval) {
mul_v3_m4v3(sctx->ret.loc, obmat, nearest2d.nearest_point.co);
sctx->ret.dist_px_sq = nearest2d.nearest_point.dist_sq;
sctx->ret.index = nearest2d.nearest_point.index;
return retval;
}
return SCE_SNAP_MODE_NONE;
return retval;
}

View File

@@ -40,12 +40,11 @@ eSnapMode snapCamera(SnapObjectContext *sctx,
return retval;
}
float orig_camera_mat[4][4], orig_camera_imat[4][4], imat[4][4];
float orig_camera_mat[4][4], orig_camera_imat[4][4];
BKE_tracking_get_camera_object_matrix(object, orig_camera_mat);
invert_m4_m4(orig_camera_imat, orig_camera_mat);
invert_m4_m4(imat, obmat);
Nearest2dUserData nearest2d(sctx, sctx->ret.dist_px_sq);
Nearest2dUserData nearest2d(sctx, object, static_cast<const ID *>(object->data));
MovieTracking *tracking = &clip->tracking;
LISTBASE_FOREACH (MovieTrackingObject *, tracking_object, &tracking->objects) {
@@ -82,13 +81,5 @@ eSnapMode snapCamera(SnapObjectContext *sctx,
}
}
if (retval) {
copy_v3_v3(sctx->ret.loc, nearest2d.nearest_point.co);
sctx->ret.dist_px_sq = nearest2d.nearest_point.dist_sq;
sctx->ret.index = nearest2d.nearest_point.index;
return retval;
}
return SCE_SNAP_MODE_NONE;
}

View File

@@ -33,7 +33,7 @@ eSnapMode snapCurve(SnapObjectContext *sctx, Object *ob_eval, const float obmat[
Curve *cu = static_cast<Curve *>(ob_eval->data);
Nearest2dUserData nearest2d(sctx, sctx->ret.dist_px_sq, float4x4(obmat));
Nearest2dUserData nearest2d(sctx, ob_eval, &cu->id, float4x4(obmat));
const bool use_obedit = BKE_object_is_in_editmode(ob_eval);
@@ -45,7 +45,7 @@ eSnapMode snapCurve(SnapObjectContext *sctx, Object *ob_eval, const float obmat[
}
}
nearest2d.clip_planes_get(sctx, float4x4(obmat), true);
nearest2d.clip_planes_get(sctx, true);
bool skip_selected = (sctx->runtime.params.snap_target_select & SCE_SNAP_TARGET_NOT_SELECTED) !=
0;
@@ -108,13 +108,6 @@ eSnapMode snapCurve(SnapObjectContext *sctx, Object *ob_eval, const float obmat[
}
}
}
if (has_snap) {
mul_v3_m4v3(sctx->ret.loc, obmat, nearest2d.nearest_point.co);
sctx->ret.dist_px_sq = nearest2d.nearest_point.dist_sq;
sctx->ret.index = nearest2d.nearest_point.index;
return SCE_SNAP_MODE_VERTEX;
}
return SCE_SNAP_MODE_NONE;
return has_snap ? SCE_SNAP_MODE_VERTEX : SCE_SNAP_MODE_NONE;
}

View File

@@ -444,7 +444,7 @@ void nearest2d_data_init_editmesh(BMEditMesh *em, Nearest2dUserData *r_nearest2d
eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
Object *ob_eval,
ID * /*id*/,
const ID * /*id*/,
const float obmat[4][4],
eSnapMode snap_to_flag,
int polygon)
@@ -458,8 +458,8 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
BMEditMesh *em = sod->treedata_editmesh.em;
Nearest2dUserData nearest2d(sctx, sctx->ret.dist_px_sq, float4x4(obmat));
nearest2d.clip_planes_get(sctx, float4x4(obmat));
Nearest2dUserData nearest2d(sctx, ob_eval, nullptr, float4x4(obmat));
nearest2d.clip_planes_get(sctx);
nearest2d_data_init_editmesh(em, &nearest2d);
BVHTreeNearest nearest{};
@@ -498,21 +498,7 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
}
if (nearest.index != -1) {
sctx->ret.dist_px_sq = nearest.dist_sq;
mul_m4_v3(obmat, nearest.co);
copy_v3_v3(sctx->ret.loc, nearest.co);
{
float imat[4][4];
invert_m4_m4(imat, obmat);
mul_transposed_mat3_m4_v3(imat, nearest.no);
normalize_v3(nearest.no);
copy_v3_v3(sctx->ret.no, nearest.no);
}
sctx->ret.index = nearest.index;
nearest2d.nearest_point = nearest;
return elem;
}
@@ -521,13 +507,14 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
SnapObjectContext *sctx,
Object *ob_eval,
BMEditMesh *em,
const float obmat[4][4],
eSnapMode snap_to_flag)
{
BLI_assert(snap_to_flag != SCE_SNAP_MODE_FACE);
Nearest2dUserData nearest2d(sctx, sctx->ret.dist_px_sq, float4x4(obmat));
Nearest2dUserData nearest2d(sctx, ob_eval, nullptr, float4x4(obmat));
/* Was BKE_boundbox_ray_hit_check, see: cf6ca226fa58. */
if (!nearest2d.snap_boundbox(sod->min, sod->max)) {
@@ -594,7 +581,7 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
}
}
nearest2d.clip_planes_get(sctx, float4x4(obmat));
nearest2d.clip_planes_get(sctx);
nearest2d_data_init_editmesh(em, &nearest2d);
BVHTreeNearest nearest{};
@@ -641,19 +628,7 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
}
if (nearest.index != -1) {
copy_v3_v3(sctx->ret.loc, nearest.co);
copy_v3_v3(sctx->ret.no, nearest.no);
mul_m4_v3(obmat, sctx->ret.loc);
float imat[4][4];
invert_m4_m4(imat, obmat);
mul_transposed_mat3_m4_v3(imat, sctx->ret.no);
normalize_v3(sctx->ret.no);
sctx->ret.dist_px_sq = nearest.dist_sq;
sctx->ret.index = nearest.index;
nearest2d.nearest_point = nearest;
return elem;
}
@@ -664,7 +639,7 @@ static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
eSnapMode snap_object_editmesh(SnapObjectContext *sctx,
Object *ob_eval,
ID * /*id*/,
const ID * /*id*/,
const float obmat[4][4],
eSnapMode snap_to_flag,
bool /*use_hide*/)
@@ -682,7 +657,7 @@ eSnapMode snap_object_editmesh(SnapObjectContext *sctx,
if (snap_mode_used & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT |
SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_VERTEX))
{
elem = snapEditMesh(sod, sctx, em, obmat, snap_to_flag);
elem = snapEditMesh(sod, sctx, ob_eval, em, obmat, snap_to_flag);
if (elem) {
return elem;
}

View File

@@ -389,18 +389,18 @@ void nearest2d_data_init_mesh(const Mesh *mesh, Nearest2dUserData *r_nearest2d)
* \{ */
eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
Object * /*ob_eval*/,
ID *id,
Object *ob_eval,
const ID *id,
const float obmat[4][4],
eSnapMode snap_to_flag,
int polygon)
{
eSnapMode elem = SCE_SNAP_MODE_NONE;
Mesh *mesh_eval = reinterpret_cast<Mesh *>(id);
const Mesh *mesh_eval = reinterpret_cast<const Mesh *>(id);
Nearest2dUserData nearest2d(sctx, sctx->ret.dist_px_sq, float4x4(obmat));
nearest2d.clip_planes_get(sctx, float4x4(obmat));
Nearest2dUserData nearest2d(sctx, ob_eval, id, float4x4(obmat));
nearest2d.clip_planes_get(sctx);
nearest2d_data_init_mesh(mesh_eval, &nearest2d);
BVHTreeNearest nearest{};
@@ -436,21 +436,7 @@ eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
}
if (nearest.index != -1) {
sctx->ret.dist_px_sq = nearest.dist_sq;
mul_m4_v3(obmat, nearest.co);
copy_v3_v3(sctx->ret.loc, nearest.co);
{
float imat[4][4];
invert_m4_m4(imat, obmat);
mul_transposed_mat3_m4_v3(imat, nearest.no);
normalize_v3(nearest.no);
copy_v3_v3(sctx->ret.no, nearest.no);
}
sctx->ret.index = nearest.index;
nearest2d.nearest_point = nearest;
return elem;
}
@@ -471,7 +457,7 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
return SCE_SNAP_MODE_NONE;
}
Nearest2dUserData nearest2d(sctx, sctx->ret.dist_px_sq, float4x4(obmat));
Nearest2dUserData nearest2d(sctx, ob_eval, &me_eval->id, float4x4(obmat));
if (ob_eval->data == me_eval) {
const BoundBox *bb = BKE_mesh_boundbox_get(ob_eval);
@@ -491,7 +477,7 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
BLI_assert(treedata_dummy.cached);
}
nearest2d.clip_planes_get(sctx, float4x4(obmat));
nearest2d.clip_planes_get(sctx);
nearest2d_data_init_mesh(me_eval, &nearest2d);
BVHTreeNearest nearest{};
@@ -582,20 +568,7 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
}
if (nearest.index != -1) {
copy_v3_v3(sctx->ret.loc, nearest.co);
copy_v3_v3(sctx->ret.no, nearest.no);
mul_m4_v3(obmat, sctx->ret.loc);
float imat[3][3];
copy_m3_m4(imat, obmat);
invert_m3(imat);
mul_transposed_m3_v3(imat, sctx->ret.no);
normalize_v3(sctx->ret.no);
sctx->ret.index = nearest.index;
sctx->ret.dist_px_sq = nearest.dist_sq;
nearest2d.nearest_point = nearest;
return elem;
}
@@ -604,7 +577,7 @@ static eSnapMode snapMesh(SnapObjectContext *sctx,
/** \} */
static eSnapMode mesh_snap_mode_supported(Mesh *mesh)
static eSnapMode mesh_snap_mode_supported(const Mesh *mesh)
{
eSnapMode snap_mode_supported = SCE_SNAP_MODE_NONE;
if (mesh->totpoly) {
@@ -622,14 +595,14 @@ static eSnapMode mesh_snap_mode_supported(Mesh *mesh)
eSnapMode snap_object_mesh(SnapObjectContext *sctx,
Object *ob_eval,
ID *id,
const ID *id,
const float obmat[4][4],
eSnapMode snap_to_flag,
bool use_hide)
{
eSnapMode elem = SCE_SNAP_MODE_NONE;
Mesh *mesh_eval = reinterpret_cast<Mesh *>(id);
const Mesh *mesh_eval = reinterpret_cast<const Mesh *>(id);
eSnapMode snap_mode_used = snap_to_flag & mesh_snap_mode_supported(mesh_eval);
if (snap_mode_used & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT |