/* Swap pairs of lattice points along a specified axis * - Helper for lattice_flip_exec() */ static void lattice_swap_point_pairs(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis) { BPoint *bpA, *bpB; int numU = lt->pntsu; int numV = lt->pntsv; int numW = lt->pntsw; int u0 = u, u1 = u; int v0 = v, v1 = v; int w0 = w, w1 = w; /* get pair index by just overriding the relevant pair-value * - "-1" else buffer overflow */ switch (axis) { case LATTICE_FLIP_U: u1 = numU - u - 1; break; case LATTICE_FLIP_V: v1 = numV - v - 1; break; case LATTICE_FLIP_W: w1 = numW - w - 1; break; } /* get points to operate on */ bpA = <->def[BKE_lattice_index_from_uvw(lt, u0, v0, w0)]; bpB = <->def[BKE_lattice_index_from_uvw(lt, u1, v1, w1)]; /* Swap all coordinates, so that flipped coordinates belong to * the indices on the correct side of the lattice. * * Coords: (-2 4) |0| (3 4) --> (3 4) |0| (-2 4) * Indices: (0,L) (1,R) --> (0,L) (1,R) */ swap_v3_v3(bpA->vec, bpB->vec); /* However, we need to mirror the coordinate values on the axis we're dealing with, * otherwise we'd have effectively only rotated the points around. If we don't do this, * we'd just be reimplementing the naive mirroring algorithm, which causes unwanted deforms * such as flipped normals, etc. * * Coords: (3 4) |0| (-2 4) --\ * \-> (-3 4) |0| (2 4) * Indices: (0,L) (1,R) --> (0,L) (1,R) */ lattice_flip_point_value(lt, u0, v0, w0, mid, axis); lattice_flip_point_value(lt, u1, v1, w1, mid, axis); }
/* Flip midpoint value so that relative distances between midpoint and neighbor-pair is maintained * ! Assumes that uvw <=> xyz (i.e. axis-aligned index-axes with coordinate-axes) * - Helper for lattice_flip_exec() */ static void lattice_flip_point_value(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis) { BPoint *bp; float diff; /* just the point in the middle (unpaired) */ bp = <->def[BKE_lattice_index_from_uvw(lt, u, v, w)]; /* flip over axis */ diff = mid - bp->vec[axis]; bp->vec[axis] = mid + diff; }
static bool lattice_test_bitmap_uvw(Lattice *lt, BLI_bitmap *selpoints, int u, int v, int w, const bool selected) { if ((u < 0 || u >= lt->pntsu) || (v < 0 || v >= lt->pntsv) || (w < 0 || w >= lt->pntsw)) { return false; } else { int i = BKE_lattice_index_from_uvw(lt, u, v, w); if (lt->def[i].hide == 0) { return (BLI_BITMAP_TEST(selpoints, i) != 0) == selected; } return false; } }
int BKE_lattice_index_flip(Lattice *lt, const int index, const bool flip_u, const bool flip_v, const bool flip_w) { int u, v, w; BKE_lattice_index_to_uvw(lt, index, &u, &v, &w); if (flip_u) { u = (lt->pntsu - 1) - u; } if (flip_v) { v = (lt->pntsv - 1) - v; } if (flip_w) { w = (lt->pntsw - 1) - w; } return BKE_lattice_index_from_uvw(lt, u, v, w); }
static BPoint *latt_bp(Lattice *lt, int u, int v, int w) { return <->def[BKE_lattice_index_from_uvw(lt, u, v, w)]; }
static bool object_shape_key_mirror(bContext *C, Object *ob, int *r_totmirr, int *r_totfail, bool use_topology) { KeyBlock *kb; Key *key; int totmirr = 0, totfail = 0; *r_totmirr = *r_totfail = 0; key = BKE_key_from_object(ob); if (key == NULL) return 0; kb = BLI_findlink(&key->block, ob->shapenr - 1); if (kb) { char *tag_elem = MEM_callocN(sizeof(char) * kb->totelem, "shape_key_mirror"); if (ob->type == OB_MESH) { Mesh *me = ob->data; MVert *mv; int i1, i2; float *fp1, *fp2; float tvec[3]; ED_mesh_mirror_spatial_table(ob, NULL, NULL, 's'); for (i1 = 0, mv = me->mvert; i1 < me->totvert; i1++, mv++) { i2 = mesh_get_x_mirror_vert(ob, i1, use_topology); if (i2 == i1) { fp1 = ((float *)kb->data) + i1 * 3; fp1[0] = -fp1[0]; tag_elem[i1] = 1; totmirr++; } else if (i2 != -1) { if (tag_elem[i1] == 0 && tag_elem[i2] == 0) { fp1 = ((float *)kb->data) + i1 * 3; fp2 = ((float *)kb->data) + i2 * 3; copy_v3_v3(tvec, fp1); copy_v3_v3(fp1, fp2); copy_v3_v3(fp2, tvec); /* flip x axis */ fp1[0] = -fp1[0]; fp2[0] = -fp2[0]; totmirr++; } tag_elem[i1] = tag_elem[i2] = 1; } else { totfail++; } } ED_mesh_mirror_spatial_table(ob, NULL, NULL, 'e'); } else if (ob->type == OB_LATTICE) { Lattice *lt = ob->data; int i1, i2; float *fp1, *fp2; int u, v, w; /* half but found up odd value */ const int pntsu_half = (lt->pntsu / 2) + (lt->pntsu % 2); /* currently editmode isn't supported by mesh so * ignore here for now too */ /* if (lt->editlatt) lt = lt->editlatt->latt; */ for (w = 0; w < lt->pntsw; w++) { for (v = 0; v < lt->pntsv; v++) { for (u = 0; u < pntsu_half; u++) { int u_inv = (lt->pntsu - 1) - u; float tvec[3]; if (u == u_inv) { i1 = BKE_lattice_index_from_uvw(lt, u, v, w); fp1 = ((float *)kb->data) + i1 * 3; fp1[0] = -fp1[0]; totmirr++; } else { i1 = BKE_lattice_index_from_uvw(lt, u, v, w); i2 = BKE_lattice_index_from_uvw(lt, u_inv, v, w); fp1 = ((float *)kb->data) + i1 * 3; fp2 = ((float *)kb->data) + i2 * 3; copy_v3_v3(tvec, fp1); copy_v3_v3(fp1, fp2); copy_v3_v3(fp2, tvec); fp1[0] = -fp1[0]; fp2[0] = -fp2[0]; totmirr++; } } } } } MEM_freeN(tag_elem); } *r_totmirr = totmirr; *r_totfail = totfail; DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return 1; }