Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2020-06-12 08:12:54 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-06-12 09:27:46 +0300
commit16595b9ea1c5c5b6f3d07a31d3aa6b4713426abc (patch)
tree683bce4f200ce2a55623801df8aefaf6bf8bffd2 /source/blender/blenkernel/intern/lattice.c
parent5549fa5466dafc2966e2e8e9658449246aa95195 (diff)
Cleanup: split object data deform functions into their own files
Move armature/curve functions into their headers, they were previously in BKE_lattice.h
Diffstat (limited to 'source/blender/blenkernel/intern/lattice.c')
-rw-r--r--source/blender/blenkernel/intern/lattice.c693
1 files changed, 0 insertions, 693 deletions
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) {