Blender  V2.59
MOD_cast.c
Go to the documentation of this file.
00001 /*
00002 * $Id: MOD_cast.c 38300 2011-07-11 09:15:20Z blendix $
00003 *
00004 * ***** BEGIN GPL LICENSE BLOCK *****
00005 *
00006 * This program is free software; you can redistribute it and/or
00007 * modify it under the terms of the GNU General Public License
00008 * as published by the Free Software Foundation; either version 2
00009 * of the License, or (at your option) any later version.
00010 *
00011 * This program is distributed in the hope that it will be useful,
00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 * GNU General Public License for more details.
00015 *
00016 * You should have received a copy of the GNU General Public License
00017 * along with this program; if not, write to the Free Software  Foundation,
00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019 *
00020 * The Original Code is Copyright (C) 2005 by the Blender Foundation.
00021 * All rights reserved.
00022 *
00023 * Contributor(s): Daniel Dunbar
00024 *                 Ton Roosendaal,
00025 *                 Ben Batt,
00026 *                 Brecht Van Lommel,
00027 *                 Campbell Barton
00028 *
00029 * ***** END GPL LICENSE BLOCK *****
00030 *
00031 */
00032 
00038 #include "DNA_meshdata_types.h"
00039 #include "DNA_object_types.h"
00040 
00041 #include "BLI_math.h"
00042 #include "BLI_utildefines.h"
00043 
00044 
00045 #include "BKE_deform.h"
00046 #include "BKE_DerivedMesh.h"
00047 #include "BKE_modifier.h"
00048 
00049 
00050 #include "depsgraph_private.h"
00051 
00052 #include "MOD_util.h"
00053 
00054 static void initData(ModifierData *md)
00055 {
00056         CastModifierData *cmd = (CastModifierData*) md;
00057 
00058         cmd->fac = 0.5f;
00059         cmd->radius = 0.0f;
00060         cmd->size = 0.0f;
00061         cmd->flag = MOD_CAST_X | MOD_CAST_Y | MOD_CAST_Z
00062                         | MOD_CAST_SIZE_FROM_RADIUS;
00063         cmd->type = MOD_CAST_TYPE_SPHERE;
00064         cmd->defgrp_name[0] = '\0';
00065         cmd->object = NULL;
00066 }
00067 
00068 
00069 static void copyData(ModifierData *md, ModifierData *target)
00070 {
00071         CastModifierData *cmd = (CastModifierData*) md;
00072         CastModifierData *tcmd = (CastModifierData*) target;
00073 
00074         tcmd->fac = cmd->fac;
00075         tcmd->radius = cmd->radius;
00076         tcmd->size = cmd->size;
00077         tcmd->flag = cmd->flag;
00078         tcmd->type = cmd->type;
00079         tcmd->object = cmd->object;
00080         strncpy(tcmd->defgrp_name, cmd->defgrp_name, 32);
00081 }
00082 
00083 static int isDisabled(ModifierData *md, int UNUSED(useRenderParams))
00084 {
00085         CastModifierData *cmd = (CastModifierData*) md;
00086         short flag;
00087         
00088         flag = cmd->flag & (MOD_CAST_X|MOD_CAST_Y|MOD_CAST_Z);
00089 
00090         if((cmd->fac == 0.0f) || flag == 0) return 1;
00091 
00092         return 0;
00093 }
00094 
00095 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
00096 {
00097         CastModifierData *cmd = (CastModifierData *)md;
00098         CustomDataMask dataMask = 0;
00099 
00100         /* ask for vertexgroups if we need them */
00101         if(cmd->defgrp_name[0]) dataMask |= CD_MASK_MDEFORMVERT;
00102 
00103         return dataMask;
00104 }
00105 
00106 static void foreachObjectLink(
00107                                            ModifierData *md, Object *ob,
00108         void (*walk)(void *userData, Object *ob, Object **obpoin),
00109                    void *userData)
00110 {
00111         CastModifierData *cmd = (CastModifierData*) md;
00112 
00113         walk (userData, ob, &cmd->object);
00114 }
00115 
00116 static void updateDepgraph(ModifierData *md, DagForest *forest,
00117                                                 struct Scene *UNUSED(scene),
00118                                                 Object *UNUSED(ob),
00119                                                 DagNode *obNode)
00120 {
00121         CastModifierData *cmd = (CastModifierData*) md;
00122 
00123         if (cmd->object) {
00124                 DagNode *curNode = dag_get_node(forest, cmd->object);
00125 
00126                 dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA,
00127                         "Cast Modifier");
00128         }
00129 }
00130 
00131 static void sphere_do(
00132                                    CastModifierData *cmd, Object *ob, DerivedMesh *dm,
00133            float (*vertexCos)[3], int numVerts)
00134 {
00135         MDeformVert *dvert = NULL;
00136 
00137         Object *ctrl_ob = NULL;
00138 
00139         int i, defgrp_index;
00140         int has_radius = 0;
00141         short flag, type;
00142         float fac, facm, len = 0.0f;
00143         float vec[3], center[3] = {0.0f, 0.0f, 0.0f};
00144         float mat[4][4], imat[4][4];
00145 
00146         fac = cmd->fac;
00147         facm = 1.0f - fac;
00148 
00149         flag = cmd->flag;
00150         type = cmd->type; /* projection type: sphere or cylinder */
00151 
00152         if (type == MOD_CAST_TYPE_CYLINDER) 
00153                 flag &= ~MOD_CAST_Z;
00154 
00155         ctrl_ob = cmd->object;
00156 
00157         /* spherify's center is {0, 0, 0} (the ob's own center in its local
00158         * space), by default, but if the user defined a control object,
00159         * we use its location, transformed to ob's local space */
00160         if (ctrl_ob) {
00161                 if(flag & MOD_CAST_USE_OB_TRANSFORM) {
00162                         invert_m4_m4(ctrl_ob->imat, ctrl_ob->obmat);
00163                         mul_m4_m4m4(mat, ob->obmat, ctrl_ob->imat);
00164                         invert_m4_m4(imat, mat);
00165                 }
00166 
00167                 invert_m4_m4(ob->imat, ob->obmat);
00168                 mul_v3_m4v3(center, ob->imat, ctrl_ob->obmat[3]);
00169         }
00170 
00171         /* now we check which options the user wants */
00172 
00173         /* 1) (flag was checked in the "if (ctrl_ob)" block above) */
00174         /* 2) cmd->radius > 0.0f: only the vertices within this radius from
00175         * the center of the effect should be deformed */
00176         if (cmd->radius > FLT_EPSILON) has_radius = 1;
00177 
00178         /* 3) if we were given a vertex group name,
00179         * only those vertices should be affected */
00180         modifier_get_vgroup(ob, dm, cmd->defgrp_name, &dvert, &defgrp_index);
00181 
00182         if(flag & MOD_CAST_SIZE_FROM_RADIUS) {
00183                 len = cmd->radius;
00184         }
00185         else {
00186                 len = cmd->size;
00187         }
00188 
00189         if(len <= 0) {
00190                 for (i = 0; i < numVerts; i++) {
00191                         len += len_v3v3(center, vertexCos[i]);
00192                 }
00193                 len /= numVerts;
00194 
00195                 if (len == 0.0f) len = 10.0f;
00196         }
00197 
00198         /* ready to apply the effect, one vertex at a time;
00199         * tiny optimization: the code is separated (with parts repeated)
00200          * in two possible cases:
00201         * with or w/o a vgroup. With lots of if's in the code below,
00202         * further optimizations are possible, if needed */
00203         if (dvert) { /* with a vgroup */
00204                 float fac_orig = fac;
00205                 for (i = 0; i < numVerts; i++) {
00206                         MDeformWeight *dw = NULL;
00207                         int j;
00208                         float tmp_co[3];
00209 
00210                         copy_v3_v3(tmp_co, vertexCos[i]);
00211                         if(ctrl_ob) {
00212                                 if(flag & MOD_CAST_USE_OB_TRANSFORM) {
00213                                         mul_m4_v3(mat, tmp_co);
00214                                 } else {
00215                                         sub_v3_v3(tmp_co, center);
00216                                 }
00217                         }
00218 
00219                         copy_v3_v3(vec, tmp_co);
00220 
00221                         if (type == MOD_CAST_TYPE_CYLINDER)
00222                                 vec[2] = 0.0f;
00223 
00224                         if (has_radius) {
00225                                 if (len_v3(vec) > cmd->radius) continue;
00226                         }
00227 
00228                         for (j = 0; j < dvert[i].totweight; ++j) {
00229                                 if(dvert[i].dw[j].def_nr == defgrp_index) {
00230                                         dw = &dvert[i].dw[j];
00231                                         break;
00232                                 }
00233                         }
00234                         if (!dw) continue;
00235 
00236                         fac = fac_orig * dw->weight;
00237                         facm = 1.0f - fac;
00238 
00239                         normalize_v3(vec);
00240 
00241                         if (flag & MOD_CAST_X)
00242                                 tmp_co[0] = fac*vec[0]*len + facm*tmp_co[0];
00243                         if (flag & MOD_CAST_Y)
00244                                 tmp_co[1] = fac*vec[1]*len + facm*tmp_co[1];
00245                         if (flag & MOD_CAST_Z)
00246                                 tmp_co[2] = fac*vec[2]*len + facm*tmp_co[2];
00247 
00248                         if(ctrl_ob) {
00249                                 if(flag & MOD_CAST_USE_OB_TRANSFORM) {
00250                                         mul_m4_v3(imat, tmp_co);
00251                                 } else {
00252                                         add_v3_v3(tmp_co, center);
00253                                 }
00254                         }
00255 
00256                         copy_v3_v3(vertexCos[i], tmp_co);
00257                 }
00258                 return;
00259         }
00260 
00261         /* no vgroup */
00262         for (i = 0; i < numVerts; i++) {
00263                 float tmp_co[3];
00264 
00265                 copy_v3_v3(tmp_co, vertexCos[i]);
00266                 if(ctrl_ob) {
00267                         if(flag & MOD_CAST_USE_OB_TRANSFORM) {
00268                                 mul_m4_v3(mat, tmp_co);
00269                         } else {
00270                                 sub_v3_v3(tmp_co, center);
00271                         }
00272                 }
00273 
00274                 copy_v3_v3(vec, tmp_co);
00275 
00276                 if (type == MOD_CAST_TYPE_CYLINDER)
00277                         vec[2] = 0.0f;
00278 
00279                 if (has_radius) {
00280                         if (len_v3(vec) > cmd->radius) continue;
00281                 }
00282 
00283                 normalize_v3(vec);
00284 
00285                 if (flag & MOD_CAST_X)
00286                         tmp_co[0] = fac*vec[0]*len + facm*tmp_co[0];
00287                 if (flag & MOD_CAST_Y)
00288                         tmp_co[1] = fac*vec[1]*len + facm*tmp_co[1];
00289                 if (flag & MOD_CAST_Z)
00290                         tmp_co[2] = fac*vec[2]*len + facm*tmp_co[2];
00291 
00292                 if(ctrl_ob) {
00293                         if(flag & MOD_CAST_USE_OB_TRANSFORM) {
00294                                 mul_m4_v3(imat, tmp_co);
00295                         } else {
00296                                 add_v3_v3(tmp_co, center);
00297                         }
00298                 }
00299 
00300                 copy_v3_v3(vertexCos[i], tmp_co);
00301         }
00302 }
00303 
00304 static void cuboid_do(
00305                                    CastModifierData *cmd, Object *ob, DerivedMesh *dm,
00306            float (*vertexCos)[3], int numVerts)
00307 {
00308         MDeformVert *dvert = NULL;
00309         Object *ctrl_ob = NULL;
00310 
00311         int i, defgrp_index;
00312         int has_radius = 0;
00313         short flag;
00314         float fac, facm;
00315         float min[3], max[3], bb[8][3];
00316         float center[3] = {0.0f, 0.0f, 0.0f};
00317         float mat[4][4], imat[4][4];
00318 
00319         fac = cmd->fac;
00320         facm = 1.0f - fac;
00321 
00322         flag = cmd->flag;
00323 
00324         ctrl_ob = cmd->object;
00325 
00326         /* now we check which options the user wants */
00327 
00328         /* 1) (flag was checked in the "if (ctrl_ob)" block above) */
00329         /* 2) cmd->radius > 0.0f: only the vertices within this radius from
00330         * the center of the effect should be deformed */
00331         if (cmd->radius > FLT_EPSILON) has_radius = 1;
00332 
00333         /* 3) if we were given a vertex group name,
00334         * only those vertices should be affected */
00335         modifier_get_vgroup(ob, dm, cmd->defgrp_name, &dvert, &defgrp_index);
00336 
00337         if (ctrl_ob) {
00338                 if(flag & MOD_CAST_USE_OB_TRANSFORM) {
00339                         invert_m4_m4(ctrl_ob->imat, ctrl_ob->obmat);
00340                         mul_m4_m4m4(mat, ob->obmat, ctrl_ob->imat);
00341                         invert_m4_m4(imat, mat);
00342                 }
00343 
00344                 invert_m4_m4(ob->imat, ob->obmat);
00345                 mul_v3_m4v3(center, ob->imat, ctrl_ob->obmat[3]);
00346         }
00347 
00348         if((flag & MOD_CAST_SIZE_FROM_RADIUS) && has_radius) {
00349                 for(i = 0; i < 3; i++) {
00350                         min[i] = -cmd->radius;
00351                         max[i] = cmd->radius;
00352                 }
00353         } else if(!(flag & MOD_CAST_SIZE_FROM_RADIUS) && cmd->size > 0) {
00354                 for(i = 0; i < 3; i++) {
00355                         min[i] = -cmd->size;
00356                         max[i] = cmd->size;
00357                 }
00358         } else {
00359                 /* get bound box */
00360                 /* We can't use the object's bound box because other modifiers
00361                 * may have changed the vertex data. */
00362                 INIT_MINMAX(min, max);
00363 
00364                 /* Cast's center is the ob's own center in its local space,
00365                 * by default, but if the user defined a control object, we use
00366                 * its location, transformed to ob's local space. */
00367                 if (ctrl_ob) {
00368                         float vec[3];
00369 
00370                         /* let the center of the ctrl_ob be part of the bound box: */
00371                         DO_MINMAX(center, min, max);
00372 
00373                         for (i = 0; i < numVerts; i++) {
00374                                 sub_v3_v3v3(vec, vertexCos[i], center);
00375                                 DO_MINMAX(vec, min, max);
00376                         }
00377                 }
00378                 else {
00379                         for (i = 0; i < numVerts; i++) {
00380                                 DO_MINMAX(vertexCos[i], min, max);
00381                         }
00382                 }
00383 
00384                 /* we want a symmetric bound box around the origin */
00385                 if (fabs(min[0]) > fabs(max[0])) max[0] = fabs(min[0]); 
00386                 if (fabs(min[1]) > fabs(max[1])) max[1] = fabs(min[1]); 
00387                 if (fabs(min[2]) > fabs(max[2])) max[2] = fabs(min[2]);
00388                 min[0] = -max[0];
00389                 min[1] = -max[1];
00390                 min[2] = -max[2];
00391         }
00392 
00393         /* building our custom bounding box */
00394         bb[0][0] = bb[2][0] = bb[4][0] = bb[6][0] = min[0];
00395         bb[1][0] = bb[3][0] = bb[5][0] = bb[7][0] = max[0];
00396         bb[0][1] = bb[1][1] = bb[4][1] = bb[5][1] = min[1];
00397         bb[2][1] = bb[3][1] = bb[6][1] = bb[7][1] = max[1];
00398         bb[0][2] = bb[1][2] = bb[2][2] = bb[3][2] = min[2];
00399         bb[4][2] = bb[5][2] = bb[6][2] = bb[7][2] = max[2];
00400 
00401         /* ready to apply the effect, one vertex at a time;
00402         * tiny optimization: the code is separated (with parts repeated)
00403          * in two possible cases:
00404         * with or w/o a vgroup. With lots of if's in the code below,
00405         * further optimizations are possible, if needed */
00406         if (dvert) { /* with a vgroup */
00407                 float fac_orig = fac;
00408                 for (i = 0; i < numVerts; i++) {
00409                         MDeformWeight *dw = NULL;
00410                         int j, octant, coord;
00411                         float d[3], dmax, apex[3], fbb;
00412                         float tmp_co[3];
00413 
00414                         copy_v3_v3(tmp_co, vertexCos[i]);
00415                         if(ctrl_ob) {
00416                                 if(flag & MOD_CAST_USE_OB_TRANSFORM) {
00417                                         mul_m4_v3(mat, tmp_co);
00418                                 } else {
00419                                         sub_v3_v3(tmp_co, center);
00420                                 }
00421                         }
00422 
00423                         if (has_radius) {
00424                                 if (fabsf(tmp_co[0]) > cmd->radius ||
00425                                                                 fabsf(tmp_co[1]) > cmd->radius ||
00426                                                                 fabsf(tmp_co[2]) > cmd->radius) continue;
00427                         }
00428 
00429                         for (j = 0; j < dvert[i].totweight; ++j) {
00430                                 if(dvert[i].dw[j].def_nr == defgrp_index) {
00431                                         dw = &dvert[i].dw[j];
00432                                         break;
00433                                 }
00434                         }
00435                         if (!dw) continue;
00436 
00437                         fac = fac_orig * dw->weight;
00438                         facm = 1.0f - fac;
00439 
00440                         /* The algo used to project the vertices to their
00441                          * bounding box (bb) is pretty simple:
00442                          * for each vertex v:
00443                         * 1) find in which octant v is in;
00444                         * 2) find which outer "wall" of that octant is closer to v;
00445                         * 3) calculate factor (var fbb) to project v to that wall;
00446                         * 4) project. */
00447 
00448                         /* find in which octant this vertex is in */
00449                         octant = 0;
00450                         if (tmp_co[0] > 0.0f) octant += 1;
00451                         if (tmp_co[1] > 0.0f) octant += 2;
00452                         if (tmp_co[2] > 0.0f) octant += 4;
00453 
00454                         /* apex is the bb's vertex at the chosen octant */
00455                         copy_v3_v3(apex, bb[octant]);
00456 
00457                         /* find which bb plane is closest to this vertex ... */
00458                         d[0] = tmp_co[0] / apex[0];
00459                         d[1] = tmp_co[1] / apex[1];
00460                         d[2] = tmp_co[2] / apex[2];
00461 
00462                         /* ... (the closest has the higher (closer to 1) d value) */
00463                         dmax = d[0];
00464                         coord = 0;
00465                         if (d[1] > dmax) {
00466                                 dmax = d[1];
00467                                 coord = 1;
00468                         }
00469                         if (d[2] > dmax) {
00470                                 /* dmax = d[2]; */ /* commented, we don't need it */
00471                                 coord = 2;
00472                         }
00473 
00474                         /* ok, now we know which coordinate of the vertex to use */
00475 
00476                         if (fabsf(tmp_co[coord]) < FLT_EPSILON) /* avoid division by zero */
00477                                 continue;
00478 
00479                         /* finally, this is the factor we wanted, to project the vertex
00480                         * to its bounding box (bb) */
00481                         fbb = apex[coord] / tmp_co[coord];
00482 
00483                         /* calculate the new vertex position */
00484                         if (flag & MOD_CAST_X)
00485                                 tmp_co[0] = facm * tmp_co[0] + fac * tmp_co[0] * fbb;
00486                         if (flag & MOD_CAST_Y)
00487                                 tmp_co[1] = facm * tmp_co[1] + fac * tmp_co[1] * fbb;
00488                         if (flag & MOD_CAST_Z)
00489                                 tmp_co[2] = facm * tmp_co[2] + fac * tmp_co[2] * fbb;
00490 
00491                         if(ctrl_ob) {
00492                                 if(flag & MOD_CAST_USE_OB_TRANSFORM) {
00493                                         mul_m4_v3(imat, tmp_co);
00494                                 } else {
00495                                         add_v3_v3(tmp_co, center);
00496                                 }
00497                         }
00498 
00499                         copy_v3_v3(vertexCos[i], tmp_co);
00500                 }
00501                 return;
00502         }
00503 
00504         /* no vgroup (check previous case for comments about the code) */
00505         for (i = 0; i < numVerts; i++) {
00506                 int octant, coord;
00507                 float d[3], dmax, fbb, apex[3];
00508                 float tmp_co[3];
00509 
00510                 copy_v3_v3(tmp_co, vertexCos[i]);
00511                 if(ctrl_ob) {
00512                         if(flag & MOD_CAST_USE_OB_TRANSFORM) {
00513                                 mul_m4_v3(mat, tmp_co);
00514                         } else {
00515                                 sub_v3_v3(tmp_co, center);
00516                         }
00517                 }
00518 
00519                 if (has_radius) {
00520                         if (fabsf(tmp_co[0]) > cmd->radius ||
00521                                                  fabsf(tmp_co[1]) > cmd->radius ||
00522                                                  fabsf(tmp_co[2]) > cmd->radius) continue;
00523                 }
00524 
00525                 octant = 0;
00526                 if (tmp_co[0] > 0.0f) octant += 1;
00527                 if (tmp_co[1] > 0.0f) octant += 2;
00528                 if (tmp_co[2] > 0.0f) octant += 4;
00529 
00530                 copy_v3_v3(apex, bb[octant]);
00531 
00532                 d[0] = tmp_co[0] / apex[0];
00533                 d[1] = tmp_co[1] / apex[1];
00534                 d[2] = tmp_co[2] / apex[2];
00535 
00536                 dmax = d[0];
00537                 coord = 0;
00538                 if (d[1] > dmax) {
00539                         dmax = d[1];
00540                         coord = 1;
00541                 }
00542                 if (d[2] > dmax) {
00543                         /* dmax = d[2]; */ /* commented, we don't need it */
00544                         coord = 2;
00545                 }
00546 
00547                 if (fabsf(tmp_co[coord]) < FLT_EPSILON)
00548                         continue;
00549 
00550                 fbb = apex[coord] / tmp_co[coord];
00551 
00552                 if (flag & MOD_CAST_X)
00553                         tmp_co[0] = facm * tmp_co[0] + fac * tmp_co[0] * fbb;
00554                 if (flag & MOD_CAST_Y)
00555                         tmp_co[1] = facm * tmp_co[1] + fac * tmp_co[1] * fbb;
00556                 if (flag & MOD_CAST_Z)
00557                         tmp_co[2] = facm * tmp_co[2] + fac * tmp_co[2] * fbb;
00558 
00559                 if(ctrl_ob) {
00560                         if(flag & MOD_CAST_USE_OB_TRANSFORM) {
00561                                 mul_m4_v3(imat, tmp_co);
00562                         } else {
00563                                 add_v3_v3(tmp_co, center);
00564                         }
00565                 }
00566 
00567                 copy_v3_v3(vertexCos[i], tmp_co);
00568         }
00569 }
00570 
00571 static void deformVerts(ModifierData *md, Object *ob,
00572                                                 DerivedMesh *derivedData,
00573                                                 float (*vertexCos)[3],
00574                                                 int numVerts,
00575                                                 int UNUSED(useRenderParams),
00576                                                 int UNUSED(isFinalCalc))
00577 {
00578         DerivedMesh *dm = NULL;
00579         CastModifierData *cmd = (CastModifierData *)md;
00580 
00581         dm = get_dm(ob, NULL, derivedData, NULL, 0);
00582 
00583         if (cmd->type == MOD_CAST_TYPE_CUBOID) {
00584                 cuboid_do(cmd, ob, dm, vertexCos, numVerts);
00585         } else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */
00586                 sphere_do(cmd, ob, dm, vertexCos, numVerts);
00587         }
00588 
00589         if(dm != derivedData)
00590                 dm->release(dm);
00591 }
00592 
00593 static void deformVertsEM(
00594                                            ModifierData *md, Object *ob, struct EditMesh *editData,
00595            DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
00596 {
00597         DerivedMesh *dm = get_dm(ob, editData, derivedData, NULL, 0);
00598         CastModifierData *cmd = (CastModifierData *)md;
00599 
00600         if (cmd->type == MOD_CAST_TYPE_CUBOID) {
00601                 cuboid_do(cmd, ob, dm, vertexCos, numVerts);
00602         } else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */
00603                 sphere_do(cmd, ob, dm, vertexCos, numVerts);
00604         }
00605 
00606         if(dm != derivedData)
00607                 dm->release(dm);
00608 }
00609 
00610 
00611 ModifierTypeInfo modifierType_Cast = {
00612         /* name */              "Cast",
00613         /* structName */        "CastModifierData",
00614         /* structSize */        sizeof(CastModifierData),
00615         /* type */              eModifierTypeType_OnlyDeform,
00616         /* flags */             eModifierTypeFlag_AcceptsCVs
00617                                                         | eModifierTypeFlag_SupportsEditmode,
00618 
00619         /* copyData */          copyData,
00620         /* deformVerts */       deformVerts,
00621         /* deformMatrices */    NULL,
00622         /* deformVertsEM */     deformVertsEM,
00623         /* deformMatricesEM */  NULL,
00624         /* applyModifier */     NULL,
00625         /* applyModifierEM */   NULL,
00626         /* initData */          initData,
00627         /* requiredDataMask */  requiredDataMask,
00628         /* freeData */          NULL,
00629         /* isDisabled */        isDisabled,
00630         /* updateDepgraph */    updateDepgraph,
00631         /* dependsOnTime */     NULL,
00632         /* dependsOnNormals */  NULL,
00633         /* foreachObjectLink */ foreachObjectLink,
00634         /* foreachIDLink */     NULL,
00635 };