| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup bke | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Deform coordinates by a lattice object (used by modifier). | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <math.h>
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_math.h"
 | 
					
						
							| 
									
										
										
										
											2021-02-14 14:20:51 +01:00
										 |  |  | #include "BLI_simd.h"
 | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | #include "BLI_task.h"
 | 
					
						
							|  |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DNA_curve_types.h"
 | 
					
						
							|  |  |  | #include "DNA_lattice_types.h"
 | 
					
						
							|  |  |  | #include "DNA_mesh_types.h"
 | 
					
						
							|  |  |  | #include "DNA_meshdata_types.h"
 | 
					
						
							|  |  |  | #include "DNA_object_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BKE_curve.h"
 | 
					
						
							|  |  |  | #include "BKE_displist.h"
 | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  | #include "BKE_editmesh.h"
 | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | #include "BKE_key.h"
 | 
					
						
							|  |  |  | #include "BKE_lattice.h"
 | 
					
						
							|  |  |  | #include "BKE_modifier.h"
 | 
					
						
							| 
									
										
										
										
											2021-03-29 10:14:53 +02:00
										 |  |  | #include "BKE_object.h"
 | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "BKE_deform.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \name Lattice Deform API
 | 
					
						
							|  |  |  |  * \{ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct LatticeDeformData { | 
					
						
							| 
									
										
										
										
											2020-10-26 11:01:18 +01:00
										 |  |  |   /* Convert from object space to deform space */ | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  |   float latmat[4][4]; | 
					
						
							| 
									
										
										
										
											2020-10-26 11:01:18 +01:00
										 |  |  |   /* Cached reference to the lattice to use for evaluation. When in edit mode this attribute
 | 
					
						
							|  |  |  |    * is set to the edit mode lattice. */ | 
					
						
							|  |  |  |   const Lattice *lt; | 
					
						
							|  |  |  |   /* Preprocessed lattice points (converted to deform space). */ | 
					
						
							|  |  |  |   float *latticedata; | 
					
						
							|  |  |  |   /* Prefetched DeformWeights of the lattice. */ | 
					
						
							|  |  |  |   float *lattice_weights; | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | } LatticeDeformData; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 16:08:34 +10:00
										 |  |  | LatticeDeformData *BKE_lattice_deform_data_create(const Object *oblatt, const Object *ob) | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | { | 
					
						
							|  |  |  |   /* we make an array with all differences */ | 
					
						
							| 
									
										
										
										
											2021-03-29 10:14:53 +02:00
										 |  |  |   Lattice *lt = BKE_object_get_lattice(oblatt); | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  |   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; | 
					
						
							| 
									
										
										
										
											2020-10-26 11:01:18 +01:00
										 |  |  |   float *lattice_weights = NULL; | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  |   float latmat[4][4]; | 
					
						
							|  |  |  |   LatticeDeformData *lattice_deform_data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bp = lt->def; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-26 11:01:18 +01:00
										 |  |  |   const int32_t num_points = lt->pntsu * lt->pntsv * lt->pntsw; | 
					
						
							|  |  |  |   /* We allocate one additional float for SSE2 optimizations. Without this
 | 
					
						
							|  |  |  |    * the SSE2 instructions for the last item would read in unallocated memory. */ | 
					
						
							|  |  |  |   fp = latticedata = MEM_mallocN(sizeof(float[3]) * num_points + sizeof(float), "latticedata"); | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* 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); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-26 11:01:18 +01:00
										 |  |  |   /* Prefetch latice deform group weights. */ | 
					
						
							|  |  |  |   int defgrp_index = -1; | 
					
						
							|  |  |  |   const MDeformVert *dvert = BKE_lattice_deform_verts_get(oblatt); | 
					
						
							|  |  |  |   if (lt->vgroup[0] && dvert) { | 
					
						
							| 
									
										
										
										
											2020-11-24 11:18:24 +01:00
										 |  |  |     defgrp_index = BKE_object_defgroup_name_index(oblatt, lt->vgroup); | 
					
						
							| 
									
										
										
										
											2020-10-26 11:01:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (defgrp_index != -1) { | 
					
						
							|  |  |  |       lattice_weights = MEM_malloc_arrayN(sizeof(float), num_points, "lattice_weights"); | 
					
						
							|  |  |  |       for (int index = 0; index < num_points; index++) { | 
					
						
							|  |  |  |         lattice_weights[index] = BKE_defvert_find_weight(dvert + index, defgrp_index); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  |   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; | 
					
						
							| 
									
										
										
										
											2020-10-26 11:01:18 +01:00
										 |  |  |   lattice_deform_data->lattice_weights = lattice_weights; | 
					
						
							|  |  |  |   lattice_deform_data->lt = lt; | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  |   copy_m4_m4(lattice_deform_data->latmat, latmat); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return lattice_deform_data; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 15:41:34 +10:00
										 |  |  | void BKE_lattice_deform_data_eval_co(LatticeDeformData *lattice_deform_data, | 
					
						
							|  |  |  |                                      float co[3], | 
					
						
							|  |  |  |                                      float weight) | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-10-26 11:01:18 +01:00
										 |  |  |   float *latticedata = lattice_deform_data->latticedata; | 
					
						
							|  |  |  |   float *lattice_weights = lattice_deform_data->lattice_weights; | 
					
						
							|  |  |  |   BLI_assert(latticedata); | 
					
						
							|  |  |  |   const Lattice *lt = lattice_deform_data->lt; | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  |   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 */ | 
					
						
							| 
									
										
										
										
											2020-10-30 14:56:32 +01:00
										 |  |  |   float co_prev[4] = {0}, weight_blend = 0.0f; | 
					
						
							| 
									
										
										
										
											2020-10-26 11:01:18 +01:00
										 |  |  |   copy_v3_v3(co_prev, co); | 
					
						
							| 
									
										
										
										
											2021-02-14 14:20:51 +01:00
										 |  |  | #ifdef BLI_HAVE_SSE2
 | 
					
						
							| 
									
										
										
										
											2020-10-26 11:01:18 +01:00
										 |  |  |   __m128 co_vec = _mm_loadu_ps(co_prev); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* 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; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-26 11:01:18 +01:00
										 |  |  |   const int w_stride = lt->pntsu * lt->pntsv; | 
					
						
							|  |  |  |   const int idx_w_max = (lt->pntsw - 1) * lt->pntsu * lt->pntsv; | 
					
						
							|  |  |  |   const int v_stride = lt->pntsu; | 
					
						
							|  |  |  |   const int idx_v_max = (lt->pntsv - 1) * lt->pntsu; | 
					
						
							|  |  |  |   const int idx_u_max = (lt->pntsu - 1); | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-26 11:01:18 +01:00
										 |  |  |   for (ww = wi - 1; ww <= wi + 2; ww++) { | 
					
						
							|  |  |  |     w = weight * tw[ww - wi + 1]; | 
					
						
							|  |  |  |     idx_w = CLAMPIS(ww * w_stride, 0, idx_w_max); | 
					
						
							|  |  |  |     for (vv = vi - 1; vv <= vi + 2; vv++) { | 
					
						
							|  |  |  |       v = w * tv[vv - vi + 1]; | 
					
						
							|  |  |  |       idx_v = CLAMPIS(vv * v_stride, 0, idx_v_max); | 
					
						
							|  |  |  |       for (uu = ui - 1; uu <= ui + 2; uu++) { | 
					
						
							|  |  |  |         u = v * tu[uu - ui + 1]; | 
					
						
							|  |  |  |         idx_u = CLAMPIS(uu, 0, idx_u_max); | 
					
						
							|  |  |  |         const int idx = idx_w + idx_v + idx_u; | 
					
						
							| 
									
										
										
										
											2021-02-14 14:20:51 +01:00
										 |  |  | #ifdef BLI_HAVE_SSE2
 | 
					
						
							| 
									
										
										
										
											2020-10-26 11:01:18 +01:00
										 |  |  |         { | 
					
						
							|  |  |  |           __m128 weight_vec = _mm_set1_ps(u); | 
					
						
							| 
									
										
										
										
											2020-10-30 15:31:01 +01:00
										 |  |  |           /* We need to address special case for last item to avoid accessing invalid memory. */ | 
					
						
							|  |  |  |           __m128 lattice_vec; | 
					
						
							|  |  |  |           if (idx * 3 == idx_w_max) { | 
					
						
							|  |  |  |             copy_v3_v3((float *)&lattice_vec, &latticedata[idx * 3]); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           else { | 
					
						
							|  |  |  |             /* When not on last item, we can safely access one extra float, it will be ignored
 | 
					
						
							|  |  |  |              * anyway. */ | 
					
						
							|  |  |  |             lattice_vec = _mm_loadu_ps(&latticedata[idx * 3]); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2020-10-26 11:01:18 +01:00
										 |  |  |           co_vec = _mm_add_ps(co_vec, _mm_mul_ps(lattice_vec, weight_vec)); | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-10-26 11:01:18 +01:00
										 |  |  | #else
 | 
					
						
							|  |  |  |         madd_v3_v3fl(co, &latticedata[idx * 3], u); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |         if (lattice_weights) { | 
					
						
							|  |  |  |           weight_blend += (u * lattice_weights[idx]); | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-02-14 14:20:51 +01:00
										 |  |  | #ifdef BLI_HAVE_SSE2
 | 
					
						
							| 
									
										
										
										
											2020-10-26 11:01:18 +01:00
										 |  |  |   { | 
					
						
							|  |  |  |     copy_v3_v3(co, (float *)&co_vec); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-26 11:01:18 +01:00
										 |  |  |   if (lattice_weights) { | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  |     interp_v3_v3v3(co, co_prev, co, weight_blend); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 15:41:34 +10:00
										 |  |  | void BKE_lattice_deform_data_destroy(LatticeDeformData *lattice_deform_data) | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | { | 
					
						
							|  |  |  |   if (lattice_deform_data->latticedata) { | 
					
						
							|  |  |  |     MEM_freeN(lattice_deform_data->latticedata); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   MEM_freeN(lattice_deform_data); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | /** \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; | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /** Specific data types. */ | 
					
						
							|  |  |  |   struct { | 
					
						
							|  |  |  |     int cd_dvert_offset; | 
					
						
							|  |  |  |   } bmesh; | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | } LatticeDeformUserdata; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  | static void lattice_deform_vert_with_dvert(const LatticeDeformUserdata *data, | 
					
						
							|  |  |  |                                            const int index, | 
					
						
							|  |  |  |                                            const MDeformVert *dvert) | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  |   if (dvert != NULL) { | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  |     const float weight = data->invert_vgroup ? | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  |                              1.0f - BKE_defvert_find_weight(dvert, data->defgrp_index) : | 
					
						
							|  |  |  |                              BKE_defvert_find_weight(dvert, data->defgrp_index); | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  |     if (weight > 0.0f) { | 
					
						
							| 
									
										
										
										
											2020-06-13 15:41:34 +10:00
										 |  |  |       BKE_lattice_deform_data_eval_co( | 
					
						
							|  |  |  |           data->lattice_deform_data, data->vert_coords[index], weight * data->fac); | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2020-06-13 15:41:34 +10:00
										 |  |  |     BKE_lattice_deform_data_eval_co( | 
					
						
							|  |  |  |         data->lattice_deform_data, data->vert_coords[index], data->fac); | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  | static void lattice_deform_vert_task(void *__restrict userdata, | 
					
						
							|  |  |  |                                      const int index, | 
					
						
							|  |  |  |                                      const TaskParallelTLS *__restrict UNUSED(tls)) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const LatticeDeformUserdata *data = userdata; | 
					
						
							|  |  |  |   lattice_deform_vert_with_dvert(data, index, data->dvert ? &data->dvert[index] : NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-09 22:49:45 +10:00
										 |  |  | static void lattice_vert_task_editmesh(void *__restrict userdata, | 
					
						
							|  |  |  |                                        MempoolIterData *iter, | 
					
						
							|  |  |  |                                        const TaskParallelTLS *__restrict UNUSED(tls)) | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  | { | 
					
						
							|  |  |  |   const LatticeDeformUserdata *data = userdata; | 
					
						
							|  |  |  |   BMVert *v = (BMVert *)iter; | 
					
						
							|  |  |  |   MDeformVert *dvert = BM_ELEM_CD_GET_VOID_P(v, data->bmesh.cd_dvert_offset); | 
					
						
							|  |  |  |   lattice_deform_vert_with_dvert(data, BM_elem_index_get(v), dvert); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-09 22:49:45 +10:00
										 |  |  | static void lattice_vert_task_editmesh_no_dvert(void *__restrict userdata, | 
					
						
							|  |  |  |                                                 MempoolIterData *iter, | 
					
						
							|  |  |  |                                                 const TaskParallelTLS *__restrict UNUSED(tls)) | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  | { | 
					
						
							|  |  |  |   const LatticeDeformUserdata *data = userdata; | 
					
						
							|  |  |  |   BMVert *v = (BMVert *)iter; | 
					
						
							|  |  |  |   lattice_deform_vert_with_dvert(data, BM_elem_index_get(v), NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 16:08:34 +10:00
										 |  |  | static void lattice_deform_coords_impl(const Object *ob_lattice, | 
					
						
							|  |  |  |                                        const Object *ob_target, | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  |                                        float (*vert_coords)[3], | 
					
						
							|  |  |  |                                        const int vert_coords_len, | 
					
						
							|  |  |  |                                        const short flag, | 
					
						
							|  |  |  |                                        const char *defgrp_name, | 
					
						
							|  |  |  |                                        const float fac, | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  |                                        const Mesh *me_target, | 
					
						
							|  |  |  |                                        BMEditMesh *em_target) | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | { | 
					
						
							|  |  |  |   LatticeDeformData *lattice_deform_data; | 
					
						
							|  |  |  |   const MDeformVert *dvert = NULL; | 
					
						
							|  |  |  |   int defgrp_index = -1; | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  |   int cd_dvert_offset = -1; | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (ob_lattice->type != OB_LATTICE) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 15:41:34 +10:00
										 |  |  |   lattice_deform_data = BKE_lattice_deform_data_create(ob_lattice, ob_target); | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* 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 */ | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  |       if (em_target) { | 
					
						
							|  |  |  |         cd_dvert_offset = CustomData_get_offset(&em_target->bm->vdata, CD_MDEFORMVERT); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else if (me_target) { | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  |         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, | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  |       .bmesh = | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |               .cd_dvert_offset = cd_dvert_offset, | 
					
						
							|  |  |  |           }, | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  |   if (em_target != NULL) { | 
					
						
							|  |  |  |     /* While this could cause an extra loop over mesh data, in most cases this will
 | 
					
						
							|  |  |  |      * have already been properly set. */ | 
					
						
							|  |  |  |     BM_mesh_elem_index_ensure(em_target->bm, BM_VERT); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-09 22:49:45 +10:00
										 |  |  |     TaskParallelSettings settings; | 
					
						
							|  |  |  |     BLI_parallel_mempool_settings_defaults(&settings); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  |     if (cd_dvert_offset != -1) { | 
					
						
							| 
									
										
										
										
											2021-06-09 22:49:45 +10:00
										 |  |  |       BLI_task_parallel_mempool( | 
					
						
							|  |  |  |           em_target->bm->vpool, &data, lattice_vert_task_editmesh, &settings); | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       BLI_task_parallel_mempool( | 
					
						
							| 
									
										
										
										
											2021-06-09 22:49:45 +10:00
										 |  |  |           em_target->bm->vpool, &data, lattice_vert_task_editmesh_no_dvert, &settings); | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     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); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 15:41:34 +10:00
										 |  |  |   BKE_lattice_deform_data_destroy(lattice_deform_data); | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 16:08:34 +10:00
										 |  |  | void BKE_lattice_deform_coords(const Object *ob_lattice, | 
					
						
							|  |  |  |                                const Object *ob_target, | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  |                                float (*vert_coords)[3], | 
					
						
							| 
									
										
										
										
											2020-07-10 08:37:35 +02:00
										 |  |  |                                const int vert_coords_len, | 
					
						
							|  |  |  |                                const short flag, | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  |                                const char *defgrp_name, | 
					
						
							|  |  |  |                                float fac) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   lattice_deform_coords_impl( | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  |       ob_lattice, ob_target, vert_coords, vert_coords_len, flag, defgrp_name, fac, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 16:08:34 +10:00
										 |  |  | void BKE_lattice_deform_coords_with_mesh(const Object *ob_lattice, | 
					
						
							|  |  |  |                                          const Object *ob_target, | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  |                                          float (*vert_coords)[3], | 
					
						
							|  |  |  |                                          const int vert_coords_len, | 
					
						
							|  |  |  |                                          const short flag, | 
					
						
							|  |  |  |                                          const char *defgrp_name, | 
					
						
							|  |  |  |                                          const float fac, | 
					
						
							|  |  |  |                                          const Mesh *me_target) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  |   lattice_deform_coords_impl(ob_lattice, | 
					
						
							|  |  |  |                              ob_target, | 
					
						
							|  |  |  |                              vert_coords, | 
					
						
							|  |  |  |                              vert_coords_len, | 
					
						
							|  |  |  |                              flag, | 
					
						
							|  |  |  |                              defgrp_name, | 
					
						
							|  |  |  |                              fac, | 
					
						
							|  |  |  |                              me_target, | 
					
						
							|  |  |  |                              NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 16:08:34 +10:00
										 |  |  | void BKE_lattice_deform_coords_with_editmesh(const struct Object *ob_lattice, | 
					
						
							|  |  |  |                                              const struct Object *ob_target, | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  |                                              float (*vert_coords)[3], | 
					
						
							|  |  |  |                                              const int vert_coords_len, | 
					
						
							|  |  |  |                                              const short flag, | 
					
						
							|  |  |  |                                              const char *defgrp_name, | 
					
						
							| 
									
										
										
										
											2020-09-04 20:59:13 +02:00
										 |  |  |                                              const float fac, | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  |                                              struct BMEditMesh *em_target) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   lattice_deform_coords_impl(ob_lattice, | 
					
						
							|  |  |  |                              ob_target, | 
					
						
							|  |  |  |                              vert_coords, | 
					
						
							|  |  |  |                              vert_coords_len, | 
					
						
							|  |  |  |                              flag, | 
					
						
							|  |  |  |                              defgrp_name, | 
					
						
							| 
									
										
										
										
											2020-09-04 20:59:13 +02:00
										 |  |  |                              fac, | 
					
						
							| 
									
										
										
										
											2020-06-13 13:14:07 +10:00
										 |  |  |                              NULL, | 
					
						
							|  |  |  |                              em_target); | 
					
						
							| 
									
										
										
										
											2020-06-12 15:12:54 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \} */ |