Refactor: use 'ob_index' to get 'ob' and 'is_space' in knife hit

We can access the object and the is_space status from the ob_index.
This is less error-prone.
This commit is contained in:
Germano Cavalcante
2024-02-17 19:38:21 -03:00
parent c8d8275674
commit 7ed02da2be

View File

@@ -107,12 +107,14 @@ struct KnifeColors {
/* Knife-tool Operator. */
struct KnifeVert {
Object *ob;
uint ob_index;
BMVert *v; /* Non-null if this is an original vert. */
ListBase edges;
ListBase faces;
/* Index of the associated object.
* -1 represents the absence of an object. */
int ob_index;
float co[3], cageco[3];
bool is_face, in_space;
bool is_cut; /* Along a cut created by user input (will draw too). */
@@ -143,8 +145,10 @@ struct KnifeLineHit {
KnifeEdge *kfe;
KnifeVert *v;
BMFace *f;
Object *ob;
uint ob_index;
/* Index of the associated object.
* -1 represents the absence of an object. */
int ob_index;
};
struct KnifePosData {
@@ -156,13 +160,17 @@ struct KnifePosData {
KnifeVert *vert;
KnifeEdge *edge;
BMFace *bmface;
Object *ob; /* Object of the vert, edge or bmface. */
uint ob_index;
/* When true, the cursor isn't over a face. */
bool is_space;
/* Index of the associated object.
* -1 represents the absence of an object. */
int ob_index;
float mval[2]; /* Mouse screen position (may be non-integral if snapped to something). */
bool is_space() const
{
return this->ob_index == -1;
}
};
struct KnifeMeasureData {
@@ -181,7 +189,7 @@ struct KnifeUndoFrame {
struct KnifeBVH {
BVHTree *tree; /* Knife Custom BVH Tree. */
BMLoop *(*looptris)[3]; /* Used by #knife_bvh_raycast_cb to store the intersecting triangles. */
uint ob_index;
int ob_index;
/* Use #bm_ray_cast_cb_elem_not_in_face_check. */
bool (*filter_cb)(BMFace *f, void *userdata);
@@ -584,9 +592,10 @@ static void knifetool_draw_angle(const KnifeTool_OpData *kcd,
float axis[3];
float arc_angle;
const float inverse_average_scale = 1 / (kcd->curr.ob->object_to_world().ptr()[0][0] +
kcd->curr.ob->object_to_world().ptr()[1][1] +
kcd->curr.ob->object_to_world().ptr()[2][2]);
Object *ob = kcd->objects[kcd->curr.ob_index];
const float inverse_average_scale = 1 / (ob->object_to_world().ptr()[0][0] +
ob->object_to_world().ptr()[1][1] +
ob->object_to_world().ptr()[2][2]);
const float px_scale =
3.0f * inverse_average_scale *
@@ -847,7 +856,7 @@ static void knifetool_draw_visible_angles(const KnifeTool_OpData *kcd)
knifetool_draw_angle(
kcd, kcd->curr.cage, kcd->prev.cage, end, kcd->curr.mval, kcd->prev.mval, end_ss, angle);
}
else if (kcd->mdata.is_stored && !kcd->prev.is_space) {
else if (kcd->mdata.is_stored && !kcd->prev.is_space()) {
float angle = angle_v3v3v3(kcd->curr.cage, kcd->prev.cage, kcd->mdata.cage);
knifetool_draw_angle(kcd,
kcd->curr.cage,
@@ -1313,7 +1322,7 @@ static void knife_bvh_raycast_cb(void *userdata,
int tottri;
tottri = 0;
uint ob_index = 0;
int ob_index = 0;
for (; ob_index < kcd->objects.size(); ob_index++) {
index -= tottri;
ob = kcd->objects[ob_index];
@@ -1370,7 +1379,7 @@ static BMFace *knife_bvh_raycast(KnifeTool_OpData *kcd,
const float radius,
float *r_dist,
float r_cagehit[3],
uint *r_ob_index)
int *r_ob_index)
{
BMFace *face;
BVHTreeRayHit hit;
@@ -1408,7 +1417,7 @@ static BMFace *knife_bvh_raycast_filter(KnifeTool_OpData *kcd,
const float radius,
float *r_dist,
float r_cagehit[3],
uint *r_ob_index,
int *r_ob_index,
bool (*filter_cb)(BMFace *f, void *userdata),
void *filter_userdata)
{
@@ -1668,7 +1677,7 @@ static KnifeEdge *new_knife_edge(KnifeTool_OpData *kcd)
}
/* Get a KnifeVert wrapper for an existing BMVert. */
static KnifeVert *get_bm_knife_vert(KnifeTool_OpData *kcd, BMVert *v, Object *ob, uint ob_index)
static KnifeVert *get_bm_knife_vert(KnifeTool_OpData *kcd, BMVert *v, int ob_index)
{
KnifeVert *kfv = static_cast<KnifeVert *>(BLI_ghash_lookup(kcd->origvertmap, v));
const float *cageco;
@@ -1685,11 +1694,11 @@ static KnifeVert *get_bm_knife_vert(KnifeTool_OpData *kcd, BMVert *v, Object *ob
}
float cageco_ws[3];
Object *ob = kcd->objects[ob_index];
mul_v3_m4v3(cageco_ws, ob->object_to_world().ptr(), cageco);
kfv = new_knife_vert(kcd, v->co, cageco_ws);
kfv->v = v;
kfv->ob = ob;
kfv->ob_index = ob_index;
BLI_ghash_insert(kcd->origvertmap, v, kfv);
@@ -1702,7 +1711,7 @@ static KnifeVert *get_bm_knife_vert(KnifeTool_OpData *kcd, BMVert *v, Object *ob
}
/* Get a KnifeEdge wrapper for an existing BMEdge. */
static KnifeEdge *get_bm_knife_edge(KnifeTool_OpData *kcd, BMEdge *e, Object *ob, uint ob_index)
static KnifeEdge *get_bm_knife_edge(KnifeTool_OpData *kcd, BMEdge *e, int ob_index)
{
KnifeEdge *kfe = static_cast<KnifeEdge *>(BLI_ghash_lookup(kcd->origedgemap, e));
if (!kfe) {
@@ -1711,8 +1720,8 @@ static KnifeEdge *get_bm_knife_edge(KnifeTool_OpData *kcd, BMEdge *e, Object *ob
kfe = new_knife_edge(kcd);
kfe->e = e;
kfe->v1 = get_bm_knife_vert(kcd, e->v1, ob, ob_index);
kfe->v2 = get_bm_knife_vert(kcd, e->v2, ob, ob_index);
kfe->v1 = get_bm_knife_vert(kcd, e->v1, ob_index);
kfe->v2 = get_bm_knife_vert(kcd, e->v2, ob_index);
knife_add_to_vert_edges(kcd, kfe);
@@ -1726,7 +1735,7 @@ static KnifeEdge *get_bm_knife_edge(KnifeTool_OpData *kcd, BMEdge *e, Object *ob
return kfe;
}
static ListBase *knife_get_face_kedges(KnifeTool_OpData *kcd, Object *ob, uint ob_index, BMFace *f)
static ListBase *knife_get_face_kedges(KnifeTool_OpData *kcd, int ob_index, BMFace *f)
{
ListBase *list = static_cast<ListBase *>(BLI_ghash_lookup(kcd->kedgefacemap, f));
@@ -1737,7 +1746,7 @@ static ListBase *knife_get_face_kedges(KnifeTool_OpData *kcd, Object *ob, uint o
list = knife_empty_list(kcd);
BM_ITER_ELEM (e, &bmiter, f, BM_EDGES_OF_FACE) {
knife_append_list(kcd, list, get_bm_knife_edge(kcd, e, ob, ob_index));
knife_append_list(kcd, list, get_bm_knife_edge(kcd, e, ob_index));
}
BLI_ghash_insert(kcd->kedgefacemap, f, list);
@@ -1748,7 +1757,7 @@ static ListBase *knife_get_face_kedges(KnifeTool_OpData *kcd, Object *ob, uint o
static void knife_edge_append_face(KnifeTool_OpData *kcd, KnifeEdge *kfe, BMFace *f)
{
knife_append_list(kcd, knife_get_face_kedges(kcd, kfe->v1->ob, kfe->v1->ob_index, f), kfe);
knife_append_list(kcd, knife_get_face_kedges(kcd, kfe->v1->ob_index, f), kfe);
knife_append_list(kcd, &kfe->faces, f);
}
@@ -1764,7 +1773,6 @@ static KnifeVert *knife_split_edge(KnifeTool_OpData *kcd,
newkfe->v1 = kfe->v1;
newkfe->v2 = new_knife_vert(kcd, co, cageco);
newkfe->v2->ob = kfe->v1->ob;
newkfe->v2->ob_index = kfe->v1->ob_index;
newkfe->v2->is_cut = true;
if (kfe->e) {
@@ -1834,7 +1842,6 @@ static void knife_join_edge(KnifeEdge *newkfe, KnifeEdge *kfe)
static void knife_start_cut(KnifeTool_OpData *kcd)
{
kcd->prev = kcd->curr;
kcd->curr.is_space = false; /* TODO: Why do we do this? */
kcd->mdata.is_stored = false;
if (kcd->prev.vert == nullptr && kcd->prev.edge == nullptr) {
@@ -2055,7 +2062,6 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd,
else {
BLI_assert(lh1->f);
kfe->v1 = new_knife_vert(kcd, lh1->hit, lh1->cagehit);
kfe->v1->ob = lh1->ob;
kfe->v1->ob_index = lh1->ob_index;
kfe->v1->is_cut = true;
kfe->v1->is_face = true;
@@ -2073,7 +2079,6 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd,
else {
BLI_assert(lh2->f);
kfe->v2 = new_knife_vert(kcd, lh2->hit, lh2->cagehit);
kfe->v2->ob = lh2->ob;
kfe->v2->ob_index = lh2->ob_index;
kfe->v2->is_cut = true;
kfe->v2->is_face = true;
@@ -2244,8 +2249,9 @@ static int sort_verts_by_dist_cb(void *co_p, const void *cur_a_p, const void *cu
}
/* Use the network of KnifeEdges and KnifeVerts accumulated to make real BMVerts and BMEdedges. */
static void knife_make_cuts(KnifeTool_OpData *kcd, Object *ob)
static void knife_make_cuts(KnifeTool_OpData *kcd, int ob_index)
{
Object *ob = kcd->objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(ob);
BMesh *bm = em->bm;
KnifeEdge *kfe;
@@ -2262,7 +2268,7 @@ static void knife_make_cuts(KnifeTool_OpData *kcd, Object *ob)
for (kfe = static_cast<KnifeEdge *>(BLI_mempool_iterstep(&iter)); kfe;
kfe = static_cast<KnifeEdge *>(BLI_mempool_iterstep(&iter)))
{
if (kfe->is_invalid || kfe->v1->ob != ob) {
if (kfe->is_invalid || kfe->v1->ob_index != ob_index) {
continue;
}
@@ -2290,7 +2296,7 @@ static void knife_make_cuts(KnifeTool_OpData *kcd, Object *ob)
for (kfv = static_cast<KnifeVert *>(BLI_mempool_iterstep(&iter)); kfv;
kfv = static_cast<KnifeVert *>(BLI_mempool_iterstep(&iter)))
{
if (kfv->v || kfv->is_invalid || kfv->ob != ob) {
if (kfv->v || kfv->is_invalid || kfv->ob_index != ob_index) {
continue; /* Already have a BMVert. */
}
LISTBASE_FOREACH (LinkData *, ref, &kfv->edges) {
@@ -2492,13 +2498,13 @@ static bool knife_ray_intersect_face(KnifeTool_OpData *kcd,
const float s[2],
const float v1[3],
const float v2[3],
Object *ob,
uint ob_index,
int ob_index,
BMFace *f,
const float face_tol_sq,
float hit_co[3],
float hit_cageco[3])
{
Object *ob = kcd->objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(ob);
int tottri, tri_i;
@@ -2543,7 +2549,7 @@ static bool knife_ray_intersect_face(KnifeTool_OpData *kcd,
}
interp_v3_v3v3v3_uv(hit_cageco, UNPACK3(tri_cos), ray_tri_uv);
/* Now check that far enough away from verts and edges. */
list = knife_get_face_kedges(kcd, ob, ob_index, f);
list = knife_get_face_kedges(kcd, ob_index, f);
LISTBASE_FOREACH (LinkData *, ref, list) {
kfe = static_cast<KnifeEdge *>(ref->data);
if (kfe->is_invalid) {
@@ -2577,7 +2583,7 @@ static void calc_ortho_extent(KnifeTool_OpData *kcd)
float ws[3];
INIT_MINMAX(min, max);
for (uint ob_index = 0; ob_index < kcd->objects.size(); ob_index++) {
for (int ob_index = 0; ob_index < kcd->objects.size(); ob_index++) {
ob = kcd->objects[ob_index];
em = BKE_editmesh_from_object(ob);
@@ -2873,7 +2879,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
faces.add(f);
fobs.add(f, ob_index);
list = knife_get_face_kedges(kcd, ob, ob_index, f);
list = knife_get_face_kedges(kcd, ob_index, f);
LISTBASE_FOREACH (LinkData *, ref, list) {
KnifeEdge *kfe = static_cast<KnifeEdge *>(ref->data);
if (kfe->is_invalid) {
@@ -2945,7 +2951,6 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
hit.kfe = kfe_hit;
}
hit.ob = v->ob;
hit.ob_index = v->ob_index;
copy_v3_v3(hit.hit, v->co);
copy_v3_v3(hit.cagehit, v->cageco);
@@ -3018,7 +3023,6 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
hit.kfe = kfe;
transform_point_by_seg_v3(
hit.hit, p_cage, kfe->v1->co, kfe->v2->co, kfe->v1->cageco, kfe->v2->cageco);
hit.ob = kfe->v1->ob;
hit.ob_index = kfe->v1->ob_index;
copy_v3_v3(hit.cagehit, p_cage);
copy_v2_v2(hit.schit, sint);
@@ -3037,16 +3041,15 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
for (BMFace *f : faces) {
float p[3], p_cage[3];
uint ob_index = fobs.lookup(f);
int ob_index = fobs.lookup(f);
ob = kcd->objects[ob_index];
if (use_hit_prev &&
knife_ray_intersect_face(kcd, s1, v1, v3, ob, ob_index, f, face_tol_sq, p, p_cage))
knife_ray_intersect_face(kcd, s1, v1, v3, ob_index, f, face_tol_sq, p, p_cage))
{
if (point_is_visible(kcd, p_cage, s1, (BMElem *)f)) {
memset(&hit, 0, sizeof(hit));
hit.f = f;
hit.ob = ob;
hit.ob_index = ob_index;
copy_v3_v3(hit.hit, p);
copy_v3_v3(hit.cagehit, p_cage);
@@ -3057,12 +3060,11 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
}
if (use_hit_curr &&
knife_ray_intersect_face(kcd, s2, v2, v4, ob, ob_index, f, face_tol_sq, p, p_cage))
knife_ray_intersect_face(kcd, s2, v2, v4, ob_index, f, face_tol_sq, p, p_cage))
{
if (point_is_visible(kcd, p_cage, s2, (BMElem *)f)) {
memset(&hit, 0, sizeof(hit));
hit.f = f;
hit.ob = ob;
hit.ob_index = ob_index;
copy_v3_v3(hit.hit, p);
copy_v3_v3(hit.cagehit, p_cage);
@@ -3108,8 +3110,7 @@ static void knife_pos_data_clear(KnifePosData *kpd)
/** \name Snapping (#knife_snap_update_from_mval)
* \{ */
static BMFace *knife_find_closest_face(
KnifeTool_OpData *kcd, Object **r_ob, uint *r_ob_index, bool *is_space, float3 &r_cageco)
static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, int *r_ob_index, float3 &r_cageco)
{
BMFace *f;
float dist = KMAXDIST;
@@ -3123,16 +3124,10 @@ static BMFace *knife_find_closest_face(
if (f && kcd->only_select && BM_elem_flag_test(f, BM_ELEM_SELECT) == 0) {
f = nullptr;
*r_ob_index = -1;
}
if (is_space) {
*is_space = !f;
}
if (f) {
*r_ob = kcd->objects[*r_ob_index];
}
else {
if (f == nullptr) {
if (kcd->is_interactive) {
/* Try to use back-buffer selection method if ray casting failed.
*
@@ -3148,6 +3143,11 @@ static BMFace *knife_find_closest_face(
* of a true coordinate on the face.
* This just puts a point 1.0f in front of the view. */
r_cageco = origin + ray_normal;
if (f) {
*r_ob_index = 0;
BLI_assert(*r_ob_index == kcd->objects.first_index_of_try(vc.obact));
}
}
}
@@ -3160,12 +3160,8 @@ static BMFace *knife_find_closest_face(
*
* Arguments `f` and `cageco` should be the result of a call to #knife_find_closest_face.
*/
static int knife_sample_screen_density_from_closest_face(KnifeTool_OpData *kcd,
const float radius,
Object *ob,
uint ob_index,
BMFace *f,
const float cageco[3])
static int knife_sample_screen_density_from_closest_face(
KnifeTool_OpData *kcd, const float radius, int ob_index, BMFace *f, const float cageco[3])
{
const float radius_sq = radius * radius;
ListBase *list;
@@ -3175,7 +3171,7 @@ static int knife_sample_screen_density_from_closest_face(KnifeTool_OpData *kcd,
knife_project_v2(kcd, cageco, sco);
list = knife_get_face_kedges(kcd, ob, ob_index, f);
list = knife_get_face_kedges(kcd, ob_index, f);
LISTBASE_FOREACH (LinkData *, ref, list) {
KnifeEdge *kfe = static_cast<KnifeEdge *>(ref->data);
int i;
@@ -3222,9 +3218,9 @@ static float knife_snap_size(KnifeTool_OpData *kcd, float maxsize)
BLI_assert(kcd->is_interactive == true);
int density = 0;
if (!kcd->curr.is_space) {
if (!kcd->curr.is_space()) {
density = float(knife_sample_screen_density_from_closest_face(
kcd, maxsize * 2.0f, kcd->curr.ob, kcd->curr.ob_index, kcd->curr.bmface, kcd->curr.cage));
kcd, maxsize * 2.0f, kcd->curr.ob_index, kcd->curr.bmface, kcd->curr.cage));
}
return density ? min_ff(maxsize / (float(density) * 0.5f), maxsize) : maxsize;
@@ -3282,8 +3278,10 @@ static void knife_interp_v3_v3v3(const KnifeTool_OpData *kcd,
}
/* p is closest point on edge to the mouse cursor. */
static KnifeEdge *knife_find_closest_edge_of_face(
KnifeTool_OpData *kcd, Object *ob, uint ob_index, BMFace *f, float cagep[3])
static KnifeEdge *knife_find_closest_edge_of_face(KnifeTool_OpData *kcd,
int ob_index,
BMFace *f,
float cagep[3])
{
float sco[2];
float maxdist;
@@ -3308,7 +3306,7 @@ static KnifeEdge *knife_find_closest_edge_of_face(
knife_project_v2(kcd, cagep, sco);
/* Look through all edges associated with this face. */
list = knife_get_face_kedges(kcd, ob, ob_index, f);
list = knife_get_face_kedges(kcd, ob_index, f);
LISTBASE_FOREACH (LinkData *, ref, list) {
KnifeEdge *kfe = static_cast<KnifeEdge *>(ref->data);
float kfv1_sco[2], kfv2_sco[2], test_cagep[3];
@@ -3374,7 +3372,6 @@ static KnifeEdge *knife_find_closest_edge_of_face(
/* Update mouse coordinates to the snapped-to edge's screen coordinates
* this is important for angle snap, which uses the previous mouse position. */
edgesnap = new_knife_vert(kcd, p, cagep);
edgesnap->ob = ob;
edgesnap->ob_index = ob_index;
knife_project_v2(kcd, edgesnap->cageco, kcd->curr.mval);
}
@@ -3616,9 +3613,10 @@ static bool knife_snap_angle_relative(KnifeTool_OpData *kcd)
}
/* Use normal global direction. */
Object *ob = kcd->objects[kcd->curr.ob_index];
float no_global[3];
copy_v3_v3(no_global, fprev->no);
mul_transposed_mat3_m4_v3(kcd->curr.ob->world_to_object().ptr(), no_global);
mul_transposed_mat3_m4_v3(ob->world_to_object().ptr(), no_global);
normalize_v3(no_global);
if (isect_ray_plane_v3_factor(curr_origin, curr_ray_normal, kcd->prev.cage, no_global, &lambda))
@@ -3719,7 +3717,7 @@ static void knife_constrain_axis(KnifeTool_OpData *kcd)
/* Constrain axes. */
Scene *scene = kcd->scene;
ViewLayer *view_layer = kcd->vc.view_layer;
Object *obedit = (kcd->prev.ob) ? kcd->prev.ob : kcd->vc.obedit;
Object *obedit = (kcd->prev.ob_index != -1) ? kcd->objects[kcd->prev.ob_index] : kcd->vc.obedit;
RegionView3D *rv3d = static_cast<RegionView3D *>(kcd->region->regiondata);
const short scene_orientation = BKE_scene_orientation_get_index(scene, SCE_ORIENT_DEFAULT);
/* Scene orientation takes priority. */
@@ -3798,13 +3796,12 @@ static bool knife_snap_update_from_mval(KnifeTool_OpData *kcd, const float mval[
}
{
kcd->curr.ob = kcd->vc.obedit;
kcd->curr.bmface = knife_find_closest_face(
kcd, &kcd->curr.ob, &kcd->curr.ob_index, &kcd->curr.is_space, kcd->curr.cage);
kcd->curr.ob_index = 0; /* Start with a valid object. */
kcd->curr.bmface = knife_find_closest_face(kcd, &kcd->curr.ob_index, kcd->curr.cage);
if (kcd->curr.bmface) {
kcd->curr.edge = knife_find_closest_edge_of_face(
kcd, kcd->curr.ob, kcd->curr.ob_index, kcd->curr.bmface, kcd->curr.cage);
kcd, kcd->curr.ob_index, kcd->curr.bmface, kcd->curr.cage);
}
if (kcd->curr.edge) {
@@ -3816,7 +3813,7 @@ static bool knife_snap_update_from_mval(KnifeTool_OpData *kcd, const float mval[
}
}
return kcd->curr.vert || kcd->curr.edge || (kcd->curr.bmface && !kcd->curr.is_space);
return kcd->curr.vert || kcd->curr.edge || (kcd->curr.bmface && !kcd->curr.is_space());
}
/**
@@ -3908,7 +3905,7 @@ static void knifetool_undo(KnifeTool_OpData *kcd)
static void knifetool_init_obinfo(KnifeTool_OpData *kcd,
Object *ob,
uint ob_index,
int ob_index,
bool use_tri_indices)
{
@@ -3937,7 +3934,7 @@ static void knifetool_init_obinfo(KnifeTool_OpData *kcd,
}
}
static void knifetool_free_obinfo(KnifeTool_OpData *kcd, uint ob_index)
static void knifetool_free_obinfo(KnifeTool_OpData *kcd, int ob_index)
{
MEM_SAFE_FREE(kcd->objects_info[ob_index].cagecos);
MEM_SAFE_FREE(kcd->objects_info[ob_index].tri_indices);
@@ -4000,7 +3997,7 @@ static void knifetool_init(ViewContext *vc,
BMEditMesh *em;
kcd->objects_info = static_cast<KnifeObjectInfo *>(
MEM_callocN(sizeof(*kcd->objects_info) * kcd->objects.size(), "knife cagecos"));
for (uint ob_index = 0; ob_index < kcd->objects.size(); ob_index++) {
for (int ob_index = 0; ob_index < kcd->objects.size(); ob_index++) {
ob = kcd->objects[ob_index];
em = BKE_editmesh_from_object(ob);
knifetool_init_obinfo(kcd, ob, ob_index, use_tri_indices);
@@ -4185,9 +4182,9 @@ static void knifetool_update_mval_i(KnifeTool_OpData *kcd, const int mval_i[2])
/** \name Finalization
* \{ */
static void knifetool_finish_single_pre(KnifeTool_OpData *kcd, Object *ob)
static void knifetool_finish_single_pre(KnifeTool_OpData *kcd, int ob_index)
{
knife_make_cuts(kcd, ob);
knife_make_cuts(kcd, ob_index);
}
/**
@@ -4211,8 +4208,8 @@ static void knifetool_finish_ex(KnifeTool_OpData *kcd)
/* Separate pre/post passes are needed because `em->looptris` recalculation from the 'post' pass
* causes triangle indices in #KnifeTool_OpData.bvh to get out of sync.
* So perform all the cuts before doing any mesh recalculation, see: #101721. */
for (Object *ob : kcd->objects) {
knifetool_finish_single_pre(kcd, ob);
for (int ob_index : kcd->objects.index_range()) {
knifetool_finish_single_pre(kcd, ob_index);
}
for (Object *ob : kcd->objects) {
knifetool_finish_single_post(kcd, ob);
@@ -4305,7 +4302,8 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
KnifeTool_OpData *kcd = static_cast<KnifeTool_OpData *>(op->customdata);
bool do_refresh = false;
if (!kcd->curr.ob || kcd->curr.ob->type != OB_MESH) {
Object *ob = (kcd->curr.ob_index != -1) ? kcd->objects[kcd->curr.ob_index] : kcd->vc.obedit;
if (!ob || ob->type != OB_MESH) {
knifetool_exit(op);
ED_workspace_status_text(C, nullptr);
return OPERATOR_FINISHED;
@@ -4313,7 +4311,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
kcd->region = kcd->vc.region;
ED_view3d_init_mats_rv3d(kcd->curr.ob, kcd->vc.rv3d); /* Needed to initialize clipping. */
ED_view3d_init_mats_rv3d(ob, kcd->vc.rv3d); /* Needed to initialize clipping. */
if (kcd->mode == MODE_PANNING) {
kcd->mode = KnifeMode(kcd->prevmode);
@@ -4896,14 +4894,15 @@ void EDBM_mesh_knife(
/* Finish. */
{
/* See #knifetool_finish_ex for why multiple passes are needed. */
for (Object *ob : kcd->objects) {
for (int ob_index : kcd->objects.index_range()) {
Object *ob = kcd->objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(ob);
if (use_tag) {
BM_mesh_elem_hflag_enable_all(em->bm, BM_EDGE, BM_ELEM_TAG, false);
}
knifetool_finish_single_pre(kcd, ob);
knifetool_finish_single_pre(kcd, ob_index);
}
for (Object *ob : kcd->objects) {