From 16595b9ea1c5c5b6f3d07a31d3aa6b4713426abc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 12 Jun 2020 15:12:54 +1000 Subject: Cleanup: split object data deform functions into their own files Move armature/curve functions into their headers, they were previously in BKE_lattice.h --- source/blender/blenkernel/intern/lattice.c | 693 ----------------------------- 1 file changed, 693 deletions(-) (limited to 'source/blender/blenkernel/intern/lattice.c') diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 666eb16c75f..c3b2fd9e35d 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -31,7 +31,6 @@ #include "BLI_bitmap.h" #include "BLI_listbase.h" #include "BLI_math.h" -#include "BLI_task.h" #include "BLI_utildefines.h" #include "BLT_translation.h" @@ -40,16 +39,13 @@ #include "DNA_defaults.h" #include "DNA_key_types.h" #include "DNA_lattice_types.h" -#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "BKE_anim_path.h" #include "BKE_curve.h" #include "BKE_displist.h" #include "BKE_idtype.h" -#include "BKE_key.h" #include "BKE_lattice.h" #include "BKE_lib_id.h" #include "BKE_lib_query.h" @@ -349,695 +345,6 @@ Lattice *BKE_lattice_copy(Main *bmain, const Lattice *lt) return lt_copy; } -typedef struct LatticeDeformData { - Object *object; - float *latticedata; - float latmat[4][4]; -} LatticeDeformData; - -LatticeDeformData *init_latt_deform(Object *oblatt, Object *ob) -{ - /* we make an array with all differences */ - Lattice *lt = oblatt->data; - BPoint *bp; - DispList *dl = oblatt->runtime.curve_cache ? - BKE_displist_find(&oblatt->runtime.curve_cache->disp, DL_VERTS) : - NULL; - const float *co = dl ? dl->verts : NULL; - float *fp, imat[4][4]; - float fu, fv, fw; - int u, v, w; - float *latticedata; - float latmat[4][4]; - LatticeDeformData *lattice_deform_data; - - if (lt->editlatt) { - lt = lt->editlatt->latt; - } - bp = lt->def; - - fp = latticedata = MEM_mallocN(sizeof(float) * 3 * lt->pntsu * lt->pntsv * lt->pntsw, - "latticedata"); - - /* for example with a particle system: (ob == NULL) */ - if (ob == NULL) { - /* in deformspace, calc matrix */ - invert_m4_m4(latmat, oblatt->obmat); - - /* back: put in deform array */ - invert_m4_m4(imat, latmat); - } - else { - /* in deformspace, calc matrix */ - invert_m4_m4(imat, oblatt->obmat); - mul_m4_m4m4(latmat, imat, ob->obmat); - - /* back: put in deform array */ - invert_m4_m4(imat, latmat); - } - - for (w = 0, fw = lt->fw; w < lt->pntsw; w++, fw += lt->dw) { - for (v = 0, fv = lt->fv; v < lt->pntsv; v++, fv += lt->dv) { - for (u = 0, fu = lt->fu; u < lt->pntsu; u++, bp++, co += 3, fp += 3, fu += lt->du) { - if (dl) { - fp[0] = co[0] - fu; - fp[1] = co[1] - fv; - fp[2] = co[2] - fw; - } - else { - fp[0] = bp->vec[0] - fu; - fp[1] = bp->vec[1] - fv; - fp[2] = bp->vec[2] - fw; - } - - mul_mat3_m4_v3(imat, fp); - } - } - } - - lattice_deform_data = MEM_mallocN(sizeof(LatticeDeformData), "Lattice Deform Data"); - lattice_deform_data->latticedata = latticedata; - lattice_deform_data->object = oblatt; - copy_m4_m4(lattice_deform_data->latmat, latmat); - - return lattice_deform_data; -} - -void calc_latt_deform(LatticeDeformData *lattice_deform_data, float co[3], float weight) -{ - Object *ob = lattice_deform_data->object; - Lattice *lt = ob->data; - float u, v, w, tu[4], tv[4], tw[4]; - float vec[3]; - int idx_w, idx_v, idx_u; - int ui, vi, wi, uu, vv, ww; - - /* vgroup influence */ - int defgrp_index = -1; - float co_prev[3], weight_blend = 0.0f; - MDeformVert *dvert = BKE_lattice_deform_verts_get(ob); - float *__restrict latticedata = lattice_deform_data->latticedata; - - if (lt->editlatt) { - lt = lt->editlatt->latt; - } - if (latticedata == NULL) { - return; - } - - if (lt->vgroup[0] && dvert) { - defgrp_index = BKE_object_defgroup_name_index(ob, lt->vgroup); - copy_v3_v3(co_prev, co); - } - - /* co is in local coords, treat with latmat */ - mul_v3_m4v3(vec, lattice_deform_data->latmat, co); - - /* u v w coords */ - - if (lt->pntsu > 1) { - u = (vec[0] - lt->fu) / lt->du; - ui = (int)floor(u); - u -= ui; - key_curve_position_weights(u, tu, lt->typeu); - } - else { - tu[0] = tu[2] = tu[3] = 0.0; - tu[1] = 1.0; - ui = 0; - } - - if (lt->pntsv > 1) { - v = (vec[1] - lt->fv) / lt->dv; - vi = (int)floor(v); - v -= vi; - key_curve_position_weights(v, tv, lt->typev); - } - else { - tv[0] = tv[2] = tv[3] = 0.0; - tv[1] = 1.0; - vi = 0; - } - - if (lt->pntsw > 1) { - w = (vec[2] - lt->fw) / lt->dw; - wi = (int)floor(w); - w -= wi; - key_curve_position_weights(w, tw, lt->typew); - } - else { - tw[0] = tw[2] = tw[3] = 0.0; - tw[1] = 1.0; - wi = 0; - } - - for (ww = wi - 1; ww <= wi + 2; ww++) { - w = tw[ww - wi + 1]; - - if (w != 0.0f) { - if (ww > 0) { - if (ww < lt->pntsw) { - idx_w = ww * lt->pntsu * lt->pntsv; - } - else { - idx_w = (lt->pntsw - 1) * lt->pntsu * lt->pntsv; - } - } - else { - idx_w = 0; - } - - for (vv = vi - 1; vv <= vi + 2; vv++) { - v = w * tv[vv - vi + 1]; - - if (v != 0.0f) { - if (vv > 0) { - if (vv < lt->pntsv) { - idx_v = idx_w + vv * lt->pntsu; - } - else { - idx_v = idx_w + (lt->pntsv - 1) * lt->pntsu; - } - } - else { - idx_v = idx_w; - } - - for (uu = ui - 1; uu <= ui + 2; uu++) { - u = weight * v * tu[uu - ui + 1]; - - if (u != 0.0f) { - if (uu > 0) { - if (uu < lt->pntsu) { - idx_u = idx_v + uu; - } - else { - idx_u = idx_v + (lt->pntsu - 1); - } - } - else { - idx_u = idx_v; - } - - madd_v3_v3fl(co, &latticedata[idx_u * 3], u); - - if (defgrp_index != -1) { - weight_blend += (u * BKE_defvert_find_weight(dvert + idx_u, defgrp_index)); - } - } - } - } - } - } - } - - if (defgrp_index != -1) { - interp_v3_v3v3(co, co_prev, co, weight_blend); - } -} - -void end_latt_deform(LatticeDeformData *lattice_deform_data) -{ - if (lattice_deform_data->latticedata) { - MEM_freeN(lattice_deform_data->latticedata); - } - - MEM_freeN(lattice_deform_data); -} - -/* -------------------------------------------------------------------- */ -/** \name Curve Deform Internal Utilities - * \{ */ - -/* calculations is in local space of deformed object - * so we store in latmat transform from path coord inside object - */ -typedef struct { - float dmin[3], dmax[3]; - float curvespace[4][4], objectspace[4][4], objectspace3[3][3]; - int no_rot_axis; -} CurveDeform; - -static void init_curve_deform(Object *par, Object *ob, CurveDeform *cd) -{ - invert_m4_m4(ob->imat, ob->obmat); - mul_m4_m4m4(cd->objectspace, ob->imat, par->obmat); - invert_m4_m4(cd->curvespace, cd->objectspace); - copy_m3_m4(cd->objectspace3, cd->objectspace); - cd->no_rot_axis = 0; -} - -/* this makes sure we can extend for non-cyclic. - * - * returns OK: 1/0 - */ -static bool where_on_path_deform( - Object *ob, float ctime, float vec[4], float dir[3], float quat[4], float *radius) -{ - BevList *bl; - float ctime1; - int cycl = 0; - - /* test for cyclic */ - bl = ob->runtime.curve_cache->bev.first; - if (!bl->nr) { - return false; - } - if (bl->poly > -1) { - cycl = 1; - } - - if (cycl == 0) { - ctime1 = CLAMPIS(ctime, 0.0f, 1.0f); - } - else { - ctime1 = ctime; - } - - /* vec needs 4 items */ - if (where_on_path(ob, ctime1, vec, dir, quat, radius, NULL)) { - - if (cycl == 0) { - Path *path = ob->runtime.curve_cache->path; - float dvec[3]; - - if (ctime < 0.0f) { - sub_v3_v3v3(dvec, path->data[1].vec, path->data[0].vec); - mul_v3_fl(dvec, ctime * (float)path->len); - add_v3_v3(vec, dvec); - if (quat) { - copy_qt_qt(quat, path->data[0].quat); - } - if (radius) { - *radius = path->data[0].radius; - } - } - else if (ctime > 1.0f) { - sub_v3_v3v3(dvec, path->data[path->len - 1].vec, path->data[path->len - 2].vec); - mul_v3_fl(dvec, (ctime - 1.0f) * (float)path->len); - add_v3_v3(vec, dvec); - if (quat) { - copy_qt_qt(quat, path->data[path->len - 1].quat); - } - if (radius) { - *radius = path->data[path->len - 1].radius; - } - /* weight - not used but could be added */ - } - } - return true; - } - return false; -} - -/* for each point, rotate & translate to curve */ -/* use path, since it has constant distances */ -/* co: local coord, result local too */ -/* returns quaternion for rotation, using cd->no_rot_axis */ -/* axis is using another define!!! */ -static bool calc_curve_deform( - Object *par, float co[3], const short axis, CurveDeform *cd, float r_quat[4]) -{ - Curve *cu = par->data; - float fac, loc[4], dir[3], new_quat[4], radius; - short index; - const bool is_neg_axis = (axis > 2); - - if (par->runtime.curve_cache == NULL) { - /* Happens with a cyclic dependencies. */ - return false; - } - - if (par->runtime.curve_cache->path == NULL) { - return false; /* happens on append, cyclic dependencies and empty curves */ - } - - /* options */ - if (is_neg_axis) { - index = axis - 3; - if (cu->flag & CU_STRETCH) { - fac = -(co[index] - cd->dmax[index]) / (cd->dmax[index] - cd->dmin[index]); - } - else { - fac = -(co[index] - cd->dmax[index]) / (par->runtime.curve_cache->path->totdist); - } - } - else { - index = axis; - if (cu->flag & CU_STRETCH) { - fac = (co[index] - cd->dmin[index]) / (cd->dmax[index] - cd->dmin[index]); - } - else { - if (LIKELY(par->runtime.curve_cache->path->totdist > FLT_EPSILON)) { - fac = +(co[index] - cd->dmin[index]) / (par->runtime.curve_cache->path->totdist); - } - else { - fac = 0.0f; - } - } - } - - if (where_on_path_deform(par, fac, loc, dir, new_quat, &radius)) { /* returns OK */ - float quat[4], cent[3]; - - if (cd->no_rot_axis) { /* set by caller */ - - /* This is not exactly the same as 2.4x, since the axis is having rotation removed rather - * than changing the axis before calculating the tilt but serves much the same purpose. */ - float dir_flat[3] = {0, 0, 0}, q[4]; - copy_v3_v3(dir_flat, dir); - dir_flat[cd->no_rot_axis - 1] = 0.0f; - - normalize_v3(dir); - normalize_v3(dir_flat); - - rotation_between_vecs_to_quat(q, dir, dir_flat); /* Could this be done faster? */ - - mul_qt_qtqt(new_quat, q, new_quat); - } - - /* Logic for 'cent' orientation * - * - * The way 'co' is copied to 'cent' may seem to have no meaning, but it does. - * - * Use a curve modifier to stretch a cube out, color each side RGB, - * positive side light, negative dark. - * view with X up (default), from the angle that you can see 3 faces RGB colors (light), - * anti-clockwise - * Notice X,Y,Z Up all have light colors and each ordered CCW. - * - * Now for Neg Up XYZ, the colors are all dark, and ordered clockwise - Campbell - * - * note: moved functions into quat_apply_track/vec_apply_track - * */ - copy_qt_qt(quat, new_quat); - copy_v3_v3(cent, co); - - /* zero the axis which is not used, - * the big block of text above now applies to these 3 lines */ - quat_apply_track( - quat, - axis, - (axis == 0 || axis == 2) ? 1 : 0); /* up flag is a dummy, set so no rotation is done */ - vec_apply_track(cent, axis); - cent[index] = 0.0f; - - /* scale if enabled */ - if (cu->flag & CU_PATH_RADIUS) { - mul_v3_fl(cent, radius); - } - - /* local rotation */ - normalize_qt(quat); - mul_qt_v3(quat, cent); - - /* translation */ - add_v3_v3v3(co, cent, loc); - - if (r_quat) { - copy_qt_qt(r_quat, quat); - } - - return true; - } - return false; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Curve Deform #BKE_curve_deform_coords API - * - * #BKE_curve_deform and related functions. - * \{ */ - -void BKE_curve_deform_coords(Object *ob_curve, - Object *ob_target, - float (*vert_coords)[3], - const int vert_coords_len, - const MDeformVert *dvert, - const int defgrp_index, - const short flag, - const short defaxis) -{ - Curve *cu; - int a; - CurveDeform cd; - const bool is_neg_axis = (defaxis > 2); - const bool invert_vgroup = (flag & MOD_CURVE_INVERT_VGROUP) != 0; - - if (ob_curve->type != OB_CURVE) { - return; - } - - cu = ob_curve->data; - - init_curve_deform(ob_curve, ob_target, &cd); - - /* dummy bounds, keep if CU_DEFORM_BOUNDS_OFF is set */ - if (is_neg_axis == false) { - cd.dmin[0] = cd.dmin[1] = cd.dmin[2] = 0.0f; - cd.dmax[0] = cd.dmax[1] = cd.dmax[2] = 1.0f; - } - else { - /* negative, these bounds give a good rest position */ - cd.dmin[0] = cd.dmin[1] = cd.dmin[2] = -1.0f; - cd.dmax[0] = cd.dmax[1] = cd.dmax[2] = 0.0f; - } - - if (dvert) { - const MDeformVert *dvert_iter; - float vec[3]; - - if (cu->flag & CU_DEFORM_BOUNDS_OFF) { - for (a = 0, dvert_iter = dvert; a < vert_coords_len; a++, dvert_iter++) { - const float weight = invert_vgroup ? - 1.0f - BKE_defvert_find_weight(dvert_iter, defgrp_index) : - BKE_defvert_find_weight(dvert_iter, defgrp_index); - - if (weight > 0.0f) { - mul_m4_v3(cd.curvespace, vert_coords[a]); - copy_v3_v3(vec, vert_coords[a]); - calc_curve_deform(ob_curve, vec, defaxis, &cd, NULL); - interp_v3_v3v3(vert_coords[a], vert_coords[a], vec, weight); - mul_m4_v3(cd.objectspace, vert_coords[a]); - } - } - } - else { - /* set mesh min/max bounds */ - INIT_MINMAX(cd.dmin, cd.dmax); - - for (a = 0, dvert_iter = dvert; a < vert_coords_len; a++, dvert_iter++) { - const float weight = invert_vgroup ? - 1.0f - BKE_defvert_find_weight(dvert_iter, defgrp_index) : - BKE_defvert_find_weight(dvert_iter, defgrp_index); - if (weight > 0.0f) { - mul_m4_v3(cd.curvespace, vert_coords[a]); - minmax_v3v3_v3(cd.dmin, cd.dmax, vert_coords[a]); - } - } - - for (a = 0, dvert_iter = dvert; a < vert_coords_len; a++, dvert_iter++) { - const float weight = invert_vgroup ? - 1.0f - BKE_defvert_find_weight(dvert_iter, defgrp_index) : - BKE_defvert_find_weight(dvert_iter, defgrp_index); - - if (weight > 0.0f) { - /* already in 'cd.curvespace', prev for loop */ - copy_v3_v3(vec, vert_coords[a]); - calc_curve_deform(ob_curve, vec, defaxis, &cd, NULL); - interp_v3_v3v3(vert_coords[a], vert_coords[a], vec, weight); - mul_m4_v3(cd.objectspace, vert_coords[a]); - } - } - } - } - else { - if (cu->flag & CU_DEFORM_BOUNDS_OFF) { - for (a = 0; a < vert_coords_len; a++) { - mul_m4_v3(cd.curvespace, vert_coords[a]); - calc_curve_deform(ob_curve, vert_coords[a], defaxis, &cd, NULL); - mul_m4_v3(cd.objectspace, vert_coords[a]); - } - } - else { - /* set mesh min max bounds */ - INIT_MINMAX(cd.dmin, cd.dmax); - - for (a = 0; a < vert_coords_len; a++) { - mul_m4_v3(cd.curvespace, vert_coords[a]); - minmax_v3v3_v3(cd.dmin, cd.dmax, vert_coords[a]); - } - - for (a = 0; a < vert_coords_len; a++) { - /* already in 'cd.curvespace', prev for loop */ - calc_curve_deform(ob_curve, vert_coords[a], defaxis, &cd, NULL); - mul_m4_v3(cd.objectspace, vert_coords[a]); - } - } - } -} - -/* input vec and orco = local coord in armature space */ -/* orco is original not-animated or deformed reference point */ -/* result written in vec and mat */ -void BKE_curve_deform_co(Object *ob_curve, - Object *ob_target, - const float orco[3], - float vec[3], - float mat[3][3], - const int no_rot_axis) -{ - CurveDeform cd; - float quat[4]; - - if (ob_curve->type != OB_CURVE) { - unit_m3(mat); - return; - } - - init_curve_deform(ob_curve, ob_target, &cd); - cd.no_rot_axis = no_rot_axis; /* option to only rotate for XY, for example */ - - copy_v3_v3(cd.dmin, orco); - copy_v3_v3(cd.dmax, orco); - - mul_m4_v3(cd.curvespace, vec); - - if (calc_curve_deform(ob_curve, vec, ob_target->trackflag, &cd, quat)) { - float qmat[3][3]; - - quat_to_mat3(qmat, quat); - mul_m3_m3m3(mat, qmat, cd.objectspace3); - } - else { - unit_m3(mat); - } - - mul_m4_v3(cd.objectspace, vec); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Lattice Deform #BKE_lattice_deform_coords API - * - * #BKE_lattice_deform_coords and related functions. - * \{ */ - -typedef struct LatticeDeformUserdata { - LatticeDeformData *lattice_deform_data; - float (*vert_coords)[3]; - const MDeformVert *dvert; - int defgrp_index; - float fac; - bool invert_vgroup; -} LatticeDeformUserdata; - -static void lattice_deform_vert_task(void *__restrict userdata, - const int index, - const TaskParallelTLS *__restrict UNUSED(tls)) -{ - const LatticeDeformUserdata *data = userdata; - - if (data->dvert != NULL) { - const float weight = data->invert_vgroup ? - 1.0f - - BKE_defvert_find_weight(data->dvert + index, data->defgrp_index) : - BKE_defvert_find_weight(data->dvert + index, data->defgrp_index); - if (weight > 0.0f) { - calc_latt_deform(data->lattice_deform_data, data->vert_coords[index], weight * data->fac); - } - } - else { - calc_latt_deform(data->lattice_deform_data, data->vert_coords[index], data->fac); - } -} - -static void lattice_deform_coords_impl(Object *ob_lattice, - Object *ob_target, - float (*vert_coords)[3], - const int vert_coords_len, - const short flag, - const char *defgrp_name, - const float fac, - const Mesh *me_target) -{ - LatticeDeformData *lattice_deform_data; - const MDeformVert *dvert = NULL; - int defgrp_index = -1; - - if (ob_lattice->type != OB_LATTICE) { - return; - } - - lattice_deform_data = init_latt_deform(ob_lattice, ob_target); - - /* Check whether to use vertex groups (only possible if ob_target is a Mesh or Lattice). - * We want either a Mesh/Lattice with no derived data, or derived data with deformverts. - */ - if (defgrp_name && defgrp_name[0] && ob_target && ELEM(ob_target->type, OB_MESH, OB_LATTICE)) { - defgrp_index = BKE_object_defgroup_name_index(ob_target, defgrp_name); - - if (defgrp_index != -1) { - /* if there's derived data without deformverts, don't use vgroups */ - if (me_target) { - dvert = CustomData_get_layer(&me_target->vdata, CD_MDEFORMVERT); - } - else if (ob_target->type == OB_LATTICE) { - dvert = ((Lattice *)ob_target->data)->dvert; - } - else { - dvert = ((Mesh *)ob_target->data)->dvert; - } - } - } - - LatticeDeformUserdata data = { - .lattice_deform_data = lattice_deform_data, - .vert_coords = vert_coords, - .dvert = dvert, - .defgrp_index = defgrp_index, - .fac = fac, - .invert_vgroup = (flag & MOD_LATTICE_INVERT_VGROUP) != 0, - }; - - TaskParallelSettings settings; - BLI_parallel_range_settings_defaults(&settings); - settings.min_iter_per_thread = 32; - BLI_task_parallel_range(0, vert_coords_len, &data, lattice_deform_vert_task, &settings); - - end_latt_deform(lattice_deform_data); -} - -void BKE_lattice_deform_coords(Object *ob_lattice, - Object *ob_target, - float (*vert_coords)[3], - int vert_coords_len, - short flag, - const char *defgrp_name, - float fac) -{ - lattice_deform_coords_impl( - ob_lattice, ob_target, vert_coords, vert_coords_len, flag, defgrp_name, fac, NULL); -} - -void BKE_lattice_deform_coords_with_mesh(Object *ob_lattice, - Object *ob_target, - float (*vert_coords)[3], - const int vert_coords_len, - const short flag, - const char *defgrp_name, - const float fac, - const Mesh *me_target) -{ - lattice_deform_coords_impl( - ob_lattice, ob_target, vert_coords, vert_coords_len, flag, defgrp_name, fac, me_target); -} - -/** \} */ - bool object_deform_mball(Object *ob, ListBase *dispbase) { if (ob->parent && ob->parent->type == OB_LATTICE && ob->partype == PARSKEL) { -- cgit v1.2.3