diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2010-04-18 06:03:19 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2010-04-18 06:03:19 +0400 |
commit | dfe2f8dc03267e041102837e92f547fb04881510 (patch) | |
tree | d9582c4667ce5b9e39e2adce40832aa4f44b4fe7 /source/blender/modifiers/intern/MOD_solidify.c | |
parent | d7e08f2d33207fdf76b1b597ef0de9dec26e3987 (diff) | |
parent | 00e46ef739cf2bfddb8805af056aa59fd3b3c71c (diff) |
Merged changes in the trunk up to revision 28247.
Diffstat (limited to 'source/blender/modifiers/intern/MOD_solidify.c')
-rw-r--r-- | source/blender/modifiers/intern/MOD_solidify.c | 649 |
1 files changed, 649 insertions, 0 deletions
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c new file mode 100644 index 00000000000..d56102f2250 --- /dev/null +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -0,0 +1,649 @@ +/* +* $Id$ +* +* ***** BEGIN GPL LICENSE BLOCK ***** +* +* 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) 2005 by the Blender Foundation. +* All rights reserved. +* +* Contributor(s): Daniel Dunbar +* Ton Roosendaal, +* Ben Batt, +* Brecht Van Lommel, +* Campbell Barton +* +* ***** END GPL LICENSE BLOCK ***** +* +*/ + +#include "DNA_meshdata_types.h" + +#include "BLI_math.h" +#include "BLI_edgehash.h" + +#include "BKE_cdderivedmesh.h" +#include "BKE_mesh.h" +#include "BKE_particle.h" +#include "BKE_deform.h" +#include "BKE_utildefines.h" + +#include "MOD_modifiertypes.h" + +#include "MEM_guardedalloc.h" + +typedef struct EdgeFaceRef { + int f1; /* init as -1 */ + int f2; +} EdgeFaceRef; + +static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) +{ + int i, numVerts, numEdges, numFaces; + MFace *mface, *mf; + MVert *mvert, *mv; + + float (*face_nors)[3]; + float *f_no; + int calc_face_nors= 0; + + numVerts = dm->getNumVerts(dm); + numEdges = dm->getNumEdges(dm); + numFaces = dm->getNumFaces(dm); + mface = dm->getFaceArray(dm); + mvert = dm->getVertArray(dm); + + /* we don't want to overwrite any referenced layers */ + + /* + Dosnt work here! + mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT); + cddm->mvert = mv; + */ + + face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL); + if(!face_nors) { + calc_face_nors = 1; + face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, numFaces); + } + + mv = mvert; + mf = mface; + + { + EdgeHash *edge_hash = BLI_edgehash_new(); + EdgeHashIterator *edge_iter; + int edge_ref_count = 0; + int ed_v1, ed_v2; /* use when getting the key */ + EdgeFaceRef *edge_ref_array = MEM_callocN(numEdges * sizeof(EdgeFaceRef), "Edge Connectivity"); + EdgeFaceRef *edge_ref; + float edge_normal[3]; + + /* This function adds an edge hash if its not there, and adds the face index */ +#define NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(EDV1, EDV2); \ + edge_ref = (EdgeFaceRef *)BLI_edgehash_lookup(edge_hash, EDV1, EDV2); \ + if (!edge_ref) { \ + edge_ref = &edge_ref_array[edge_ref_count]; edge_ref_count++; \ + edge_ref->f1=i; \ + edge_ref->f2=-1; \ + BLI_edgehash_insert(edge_hash, EDV1, EDV2, edge_ref); \ + } else { \ + edge_ref->f2=i; \ + } + + for(i = 0; i < numFaces; i++, mf++) { + f_no = face_nors[i]; + + if(mf->v4) { + if(calc_face_nors) + normal_quad_v3(f_no, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co); + + NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v1, mf->v2); + NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v2, mf->v3); + NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v3, mf->v4); + NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v4, mf->v1); + } else { + if(calc_face_nors) + normal_tri_v3(f_no, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co); + + NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v1, mf->v2); + NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v2, mf->v3); + NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v3, mf->v1); + } + } + + for(edge_iter = BLI_edgehashIterator_new(edge_hash); !BLI_edgehashIterator_isDone(edge_iter); BLI_edgehashIterator_step(edge_iter)) { + /* Get the edge vert indicies, and edge value (the face indicies that use it)*/ + BLI_edgehashIterator_getKey(edge_iter, (int*)&ed_v1, (int*)&ed_v2); + edge_ref = BLI_edgehashIterator_getValue(edge_iter); + + if (edge_ref->f2 != -1) { + /* We have 2 faces using this edge, calculate the edges normal + * using the angle between the 2 faces as a weighting */ + add_v3_v3v3(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]); + normalize_v3(edge_normal); + mul_v3_fl(edge_normal, angle_normalized_v3v3(face_nors[edge_ref->f1], face_nors[edge_ref->f2])); + } else { + /* only one face attached to that edge */ + /* an edge without another attached- the weight on this is + * undefined, M_PI/2 is 90d in radians and that seems good enough */ + mul_v3_v3fl(edge_normal, face_nors[edge_ref->f1], M_PI/2); + } + add_v3_v3(temp_nors[ed_v1], edge_normal); + add_v3_v3(temp_nors[ed_v2], edge_normal); + } + BLI_edgehashIterator_free(edge_iter); + BLI_edgehash_free(edge_hash, NULL); + MEM_freeN(edge_ref_array); + } + + /* normalize vertex normals and assign */ + for(i = 0; i < numVerts; i++, mv++) { + if(normalize_v3(temp_nors[i]) == 0.0f) { + normal_short_to_float_v3(temp_nors[i], mv->no); + } + } +} + +static void initData(ModifierData *md) +{ + SolidifyModifierData *smd = (SolidifyModifierData*) md; + smd->offset = 0.01f; + smd->flag = MOD_SOLIDIFY_RIM; +} + +static void copyData(ModifierData *md, ModifierData *target) +{ + SolidifyModifierData *smd = (SolidifyModifierData*) md; + SolidifyModifierData *tsmd = (SolidifyModifierData*) target; + tsmd->offset = smd->offset; + tsmd->offset_fac = smd->offset_fac; + tsmd->crease_inner = smd->crease_inner; + tsmd->crease_outer = smd->crease_outer; + tsmd->crease_rim = smd->crease_rim; + tsmd->flag = smd->flag; + strcpy(tsmd->defgrp_name, smd->defgrp_name); +} + +static DerivedMesh *applyModifier(ModifierData *md, + Object *ob, + DerivedMesh *dm, + int useRenderParams, + int isFinalCalc) +{ + int i; + DerivedMesh *result; + SolidifyModifierData *smd = (SolidifyModifierData*) md; + + MFace *mf, *mface, *orig_mface; + MEdge *ed, *medge, *orig_medge; + MVert *mv, *mvert, *orig_mvert; + + int numVerts = dm->getNumVerts(dm); + int numEdges = dm->getNumEdges(dm); + int numFaces = dm->getNumFaces(dm); + + /* use for edges */ + int *new_vert_arr= NULL; + int newFaces = 0; + + int *new_edge_arr= NULL; + int newEdges = 0; + + int *edge_users= NULL; + char *edge_order= NULL; + + float (*vert_nors)[3]= NULL; + + float ofs_orig= - (((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset); + float ofs_new= smd->offset - (((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset); + + /* weights */ + MDeformVert *dvert= NULL, *dv= NULL; + int defgrp_index= -1; + int defgrp_invert = ((smd->flag & MOD_SOLIDIFY_VGROUP_INV) != 0); + + defgrp_index= defgroup_name_index(ob, smd->defgrp_name); + + if (defgrp_index >= 0) + dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); + + orig_mface = dm->getFaceArray(dm); + orig_medge = dm->getEdgeArray(dm); + orig_mvert = dm->getVertArray(dm); + + if(smd->flag & MOD_SOLIDIFY_RIM) { + EdgeHash *edgehash = BLI_edgehash_new(); + EdgeHashIterator *ehi; + int v1, v2; + int eidx; + + for(i=0, mv=orig_mvert; i<numVerts; i++, mv++) { + mv->flag &= ~ME_VERT_TMP_TAG; + } + + for(i=0, ed=orig_medge; i<numEdges; i++, ed++) { + BLI_edgehash_insert(edgehash, ed->v1, ed->v2, SET_INT_IN_POINTER(i)); + } + +#define INVALID_UNUSED -1 +#define INVALID_PAIR -2 + +#define ADD_EDGE_USER(_v1, _v2, edge_ord) \ + eidx= GET_INT_FROM_POINTER(BLI_edgehash_lookup(edgehash, _v1, _v2)); \ + if(edge_users[eidx] == INVALID_UNUSED) { \ + ed= orig_medge + eidx; \ + edge_users[eidx]= (_v1 < _v2) == (ed->v1 < ed->v2) ? i:(i+numFaces); \ + edge_order[eidx]= edge_ord; \ + } else { \ + edge_users[eidx]= INVALID_PAIR; \ + } \ + + + edge_users= MEM_mallocN(sizeof(int) * numEdges, "solid_mod edges"); + edge_order= MEM_mallocN(sizeof(char) * numEdges, "solid_mod eorder"); + memset(edge_users, INVALID_UNUSED, sizeof(int) * numEdges); + + for(i=0, mf=orig_mface; i<numFaces; i++, mf++) { + if(mf->v4) { + ADD_EDGE_USER(mf->v1, mf->v2, 0); + ADD_EDGE_USER(mf->v2, mf->v3, 1); + ADD_EDGE_USER(mf->v3, mf->v4, 2); + ADD_EDGE_USER(mf->v4, mf->v1, 3); + } + else { + ADD_EDGE_USER(mf->v1, mf->v2, 0); + ADD_EDGE_USER(mf->v2, mf->v3, 1); + ADD_EDGE_USER(mf->v3, mf->v1, 2); + } + } + +#undef ADD_EDGE_USER +#undef INVALID_UNUSED +#undef INVALID_PAIR + + + new_edge_arr= MEM_callocN(sizeof(int) * numEdges, "solid_mod arr"); + + ehi= BLI_edgehashIterator_new(edgehash); + for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { + int eidx= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi)); + if(edge_users[eidx] >= 0) { + BLI_edgehashIterator_getKey(ehi, &v1, &v2); + orig_mvert[v1].flag |= ME_VERT_TMP_TAG; + orig_mvert[v2].flag |= ME_VERT_TMP_TAG; + new_edge_arr[newFaces]= eidx; + newFaces++; + } + } + BLI_edgehashIterator_free(ehi); + + + + new_vert_arr= MEM_callocN(sizeof(int) * numVerts, "solid_mod new_varr"); + for(i=0, mv=orig_mvert; i<numVerts; i++, mv++) { + if(mv->flag & ME_VERT_TMP_TAG) { + new_vert_arr[newEdges] = i; + newEdges++; + + mv->flag &= ~ME_VERT_TMP_TAG; + } + } + + BLI_edgehash_free(edgehash, NULL); + } + + if(smd->flag & MOD_SOLIDIFY_NORMAL_CALC) { + vert_nors= MEM_callocN(sizeof(float) * numVerts * 3, "mod_solid_vno_hq"); + dm_calc_normal(dm, vert_nors); + } + + result = CDDM_from_template(dm, numVerts * 2, (numEdges * 2) + newEdges, (numFaces * 2) + newFaces); + + mface = result->getFaceArray(result); + medge = result->getEdgeArray(result); + mvert = result->getVertArray(result); + + DM_copy_face_data(dm, result, 0, 0, numFaces); + DM_copy_face_data(dm, result, 0, numFaces, numFaces); + + DM_copy_edge_data(dm, result, 0, 0, numEdges); + DM_copy_edge_data(dm, result, 0, numEdges, numEdges); + + DM_copy_vert_data(dm, result, 0, 0, numVerts); + DM_copy_vert_data(dm, result, 0, numVerts, numVerts); + + { + static int corner_indices[4] = {2, 1, 0, 3}; + int is_quad; + + for(i=0, mf=mface+numFaces; i<numFaces; i++, mf++) { + mf->v1 += numVerts; + mf->v2 += numVerts; + mf->v3 += numVerts; + if(mf->v4) + mf->v4 += numVerts; + + /* Flip face normal */ + { + is_quad = mf->v4; + SWAP(int, mf->v1, mf->v3); + DM_swap_face_data(result, i+numFaces, corner_indices); + test_index_face(mf, &result->faceData, numFaces, is_quad ? 4:3); + } + } + } + + for(i=0, ed=medge+numEdges; i<numEdges; i++, ed++) { + ed->v1 += numVerts; + ed->v2 += numVerts; + } + + /* note, copied vertex layers dont have flipped normals yet. do this after applying offset */ + if((smd->flag & MOD_SOLIDIFY_EVEN) == 0) { + /* no even thickness, very simple */ + float scalar_short; + float scalar_short_vgroup; + + + if(ofs_new != 0.0f) { + scalar_short= scalar_short_vgroup= ofs_new / 32767.0f; + mv= mvert + ((ofs_new >= ofs_orig) ? 0 : numVerts); + dv= dvert; + for(i=0; i<numVerts; i++, mv++) { + if(dv) { + if(defgrp_invert) scalar_short_vgroup = scalar_short * (1.0f - defvert_find_weight(dv, defgrp_index)); + else scalar_short_vgroup = scalar_short * defvert_find_weight(dv, defgrp_index); + dv++; + } + VECADDFAC(mv->co, mv->co, mv->no, scalar_short_vgroup); + } + } + + if(ofs_orig != 0.0f) { + scalar_short= scalar_short_vgroup= ofs_orig / 32767.0f; + mv= mvert + ((ofs_new >= ofs_orig) ? numVerts : 0); /* same as above but swapped, intentional use of 'ofs_new' */ + dv= dvert; + for(i=0; i<numVerts; i++, mv++) { + if(dv) { + if(defgrp_invert) scalar_short_vgroup = scalar_short * (1.0f - defvert_find_weight(dv, defgrp_index)); + else scalar_short_vgroup = scalar_short * defvert_find_weight(dv, defgrp_index); + dv++; + } + VECADDFAC(mv->co, mv->co, mv->no, scalar_short_vgroup); + } + } + + } + else { + /* make a face normal layer if not present */ + float (*face_nors)[3]; + int face_nors_calc= 0; + + /* same as EM_solidify() in editmesh_lib.c */ + float *vert_angles= MEM_callocN(sizeof(float) * numVerts * 2, "mod_solid_pair"); /* 2 in 1 */ + float *vert_accum= vert_angles + numVerts; + float face_angles[4]; + int i, j, vidx; + + face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL); + if(!face_nors) { + face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, dm->numFaceData); + face_nors_calc= 1; + } + + if(vert_nors==NULL) { + vert_nors= MEM_mallocN(sizeof(float) * numVerts * 3, "mod_solid_vno"); + for(i=0, mv=mvert; i<numVerts; i++, mv++) { + normal_short_to_float_v3(vert_nors[i], mv->no); + } + } + + for(i=0, mf=mface; i<numFaces; i++, mf++) { + + /* just added, calc the normal */ + if(face_nors_calc) { + if(mf->v4) + normal_quad_v3(face_nors[i], mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co); + else + normal_tri_v3(face_nors[i] , mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co); + } + + if(mf->v4) { + angle_quad_v3(face_angles, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co); + j= 3; + } + else { + angle_tri_v3(face_angles, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co); + j= 2; + } + + for(; j>=0; j--) { + vidx = *(&mf->v1 + j); + vert_accum[vidx] += face_angles[j]; + vert_angles[vidx]+= shell_angle_to_dist(angle_normalized_v3v3(vert_nors[vidx], face_nors[i])) * face_angles[j]; + } + } + + /* vertex group support */ + if(dvert) { + dv= dvert; + if(defgrp_invert) { + for(i=0; i<numVerts; i++, dv++) { + vert_angles[i] *= (1.0f - defvert_find_weight(dv, defgrp_index)); + } + } + else { + for(i=0; i<numVerts; i++, dv++) { + vert_angles[i] *= defvert_find_weight(dv, defgrp_index); + } + } + } + + if(ofs_new) { + mv= mvert + ((ofs_new >= ofs_orig) ? 0 : numVerts); + + for(i=0; i<numVerts; i++, mv++) { + if(vert_accum[i]) { /* zero if unselected */ + madd_v3_v3fl(mv->co, vert_nors[i], ofs_new * (vert_angles[i] / vert_accum[i])); + } + } + } + + if(ofs_orig) { + mv= mvert + ((ofs_new >= ofs_orig) ? numVerts : 0); /* same as above but swapped, intentional use of 'ofs_new' */ + + for(i=0; i<numVerts; i++, mv++) { + if(vert_accum[i]) { /* zero if unselected */ + madd_v3_v3fl(mv->co, vert_nors[i], ofs_orig * (vert_angles[i] / vert_accum[i])); + } + } + } + + MEM_freeN(vert_angles); + } + + if(vert_nors) + MEM_freeN(vert_nors); + + /* flip vertex normals for copied verts */ + mv= mvert + numVerts; + for(i=0; i<numVerts; i++, mv++) { + mv->no[0]= -mv->no[0]; + mv->no[1]= -mv->no[1]; + mv->no[2]= -mv->no[2]; + } + + if(smd->flag & MOD_SOLIDIFY_RIM) { + + + /* bugger, need to re-calculate the normals for the new edge faces. + * This could be done in many ways, but probably the quickest way is to calculate the average normals for side faces only. + * Then blend them with the normals of the edge verts. + * + * at the moment its easiest to allocate an entire array for every vertex, even though we only need edge verts - campbell + */ + +#define SOLIDIFY_SIDE_NORMALS + +#ifdef SOLIDIFY_SIDE_NORMALS + /* annoying to allocate these since we only need the edge verts, */ + float (*edge_vert_nos)[3]= MEM_callocN(sizeof(float) * numVerts * 3, "solidify_edge_nos"); + float nor[3]; +#endif + + const unsigned char crease_rim= smd->crease_rim * 255.0f; + const unsigned char crease_outer= smd->crease_outer * 255.0f; + const unsigned char crease_inner= smd->crease_inner * 255.0f; + + const int edge_indices[4][4] = { + {1, 0, 0, 1}, + {2, 1, 1, 2}, + {3, 2, 2, 3}, + {0, 3, 3, 0}}; + + /* add faces & edges */ + ed= medge + (numEdges * 2); + for(i=0; i<newEdges; i++, ed++) { + ed->v1= new_vert_arr[i]; + ed->v2= new_vert_arr[i] + numVerts; + ed->flag |= ME_EDGEDRAW; + + if(crease_rim) + ed->crease= crease_rim; + } + + /* faces */ + mf= mface + (numFaces * 2); + for(i=0; i<newFaces; i++, mf++) { + int eidx= new_edge_arr[i]; + int fidx= edge_users[eidx]; + int flip; + + if(fidx >= numFaces) { + fidx -= numFaces; + flip= 1; + } + else { + flip= 0; + } + + ed= medge + eidx; + + /* copy most of the face settings */ + DM_copy_face_data(dm, result, fidx, (numFaces * 2) + i, 1); + + if(flip) { + DM_swap_face_data(result, (numFaces * 2) + i, edge_indices[edge_order[eidx]]); + + mf->v1= ed->v1; + mf->v2= ed->v2; + mf->v3= ed->v2 + numVerts; + mf->v4= ed->v1 + numVerts; + } + else { + DM_swap_face_data(result, (numFaces * 2) + i, edge_indices[edge_order[eidx]]); + + mf->v1= ed->v2; + mf->v2= ed->v1; + mf->v3= ed->v1 + numVerts; + mf->v4= ed->v2 + numVerts; + } + + if(crease_outer) + ed->crease= crease_outer; + + if(crease_inner) { + medge[numEdges + eidx].crease= crease_inner; + } + +#ifdef SOLIDIFY_SIDE_NORMALS + normal_quad_v3(nor, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co); + + add_v3_v3(edge_vert_nos[ed->v1], nor); + add_v3_v3(edge_vert_nos[ed->v2], nor); +#endif + } + +#ifdef SOLIDIFY_SIDE_NORMALS + ed= medge + (numEdges * 2); + for(i=0; i<newEdges; i++, ed++) { + float nor_cpy[3]; + short *nor_short; + int j; + + /* note, only the first vertex (lower half of the index) is calculated */ + normalize_v3_v3(nor_cpy, edge_vert_nos[ed->v1]); + + for(j=0; j<2; j++) { /* loop over both verts of the edge */ + nor_short= mvert[*(&ed->v1 + j)].no; + normal_short_to_float_v3(nor, nor_short); + add_v3_v3(nor, nor_cpy); + normalize_v3(nor); + normal_float_to_short_v3(nor_short, nor); + } + } + + MEM_freeN(edge_vert_nos); +#endif + + MEM_freeN(new_vert_arr); + MEM_freeN(new_edge_arr); + MEM_freeN(edge_users); + MEM_freeN(edge_order); + } + + return result; +} + +#undef SOLIDIFY_SIDE_NORMALS + +static DerivedMesh *applyModifierEM(ModifierData *md, + Object *ob, + struct EditMesh *editData, + DerivedMesh *derivedData) +{ + return applyModifier(md, ob, derivedData, 0, 1); +} + + +ModifierTypeInfo modifierType_Solidify = { + /* name */ "Solidify", + /* structName */ "SolidifyModifierData", + /* structSize */ sizeof(SolidifyModifierData), + /* type */ eModifierTypeType_Constructive, + + /* flags */ eModifierTypeFlag_AcceptsMesh + | eModifierTypeFlag_AcceptsCVs + | eModifierTypeFlag_SupportsMapping + | eModifierTypeFlag_SupportsEditmode + | eModifierTypeFlag_EnableInEditmode, + + /* copyData */ copyData, + /* deformVerts */ 0, + /* deformVertsEM */ 0, + /* deformMatricesEM */ 0, + /* applyModifier */ applyModifier, + /* applyModifierEM */ applyModifierEM, + /* initData */ initData, + /* requiredDataMask */ 0, + /* freeData */ 0, + /* isDisabled */ 0, + /* updateDepgraph */ 0, + /* dependsOnTime */ 0, + /* foreachObjectLink */ 0, + /* foreachIDLink */ 0, +}; |