Blender  V2.59
MOD_cloth.c
Go to the documentation of this file.
00001 /*
00002 * $Id: MOD_cloth.c 37326 2011-06-09 02:47:22Z campbellbarton $
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_cloth_types.h"
00039 #include "DNA_scene_types.h"
00040 #include "DNA_object_types.h"
00041 
00042 #include "MEM_guardedalloc.h"
00043 
00044 #include "BLI_utildefines.h"
00045 
00046 
00047 #include "BKE_cloth.h"
00048 #include "BKE_cdderivedmesh.h"
00049 #include "BKE_global.h"
00050 #include "BKE_modifier.h"
00051 #include "BKE_pointcache.h"
00052 
00053 #include "depsgraph_private.h"
00054 
00055 #include "MOD_util.h"
00056 
00057 static void initData(ModifierData *md) 
00058 {
00059         ClothModifierData *clmd = (ClothModifierData*) md;
00060         
00061         clmd->sim_parms = MEM_callocN(sizeof(ClothSimSettings), "cloth sim parms");
00062         clmd->coll_parms = MEM_callocN(sizeof(ClothCollSettings), "cloth coll parms");
00063         clmd->point_cache = BKE_ptcache_add(&clmd->ptcaches);
00064         
00065         /* check for alloc failing */
00066         if(!clmd->sim_parms || !clmd->coll_parms || !clmd->point_cache)
00067                 return;
00068         
00069         cloth_init (clmd);
00070 }
00071 
00072 static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
00073                                                 DerivedMesh *dm,
00074                                                 int UNUSED(useRenderParams),
00075                                                 int UNUSED(isFinalCalc))
00076 {
00077         ClothModifierData *clmd = (ClothModifierData*) md;
00078         DerivedMesh *result=NULL;
00079         
00080         /* check for alloc failing */
00081         if(!clmd->sim_parms || !clmd->coll_parms)
00082         {
00083                 initData(md);
00084                 
00085                 if(!clmd->sim_parms || !clmd->coll_parms)
00086                         return dm;
00087         }
00088 
00089         result = clothModifier_do(clmd, md->scene, ob, dm);
00090 
00091         if(result)
00092         {
00093                 CDDM_calc_normals(result);
00094                 return result;
00095         }
00096         return dm;
00097 }
00098 
00099 static void updateDepgraph(
00100                                          ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
00101           DagNode *obNode)
00102 {
00103         ClothModifierData *clmd = (ClothModifierData*) md;
00104         
00105         Base *base;
00106         
00107         if(clmd)
00108         {
00109                 for(base = scene->base.first; base; base= base->next) 
00110                 {
00111                         Object *ob1= base->object;
00112                         if(ob1 != ob)
00113                         {
00114                                 CollisionModifierData *coll_clmd = (CollisionModifierData *)modifiers_findByType(ob1, eModifierType_Collision);
00115                                 if(coll_clmd)
00116                                 {
00117                                         DagNode *curNode = dag_get_node(forest, ob1);
00118                                         dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Cloth Collision");
00119                                 }
00120                         }
00121                 }
00122         }
00123 }
00124 
00125 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
00126 {
00127         CustomDataMask dataMask = 0;
00128         ClothModifierData *clmd = (ClothModifierData*)md;
00129 
00130         if(cloth_uses_vgroup(clmd))
00131                 dataMask |= CD_MASK_MDEFORMVERT;
00132 
00133         if(clmd->sim_parms->shapekey_rest != 0)
00134                 dataMask |= CD_MASK_CLOTH_ORCO;
00135 
00136         return dataMask;
00137 }
00138 
00139 static void copyData(ModifierData *md, ModifierData *target)
00140 {
00141         ClothModifierData *clmd = (ClothModifierData*) md;
00142         ClothModifierData *tclmd = (ClothModifierData*) target;
00143 
00144         if(tclmd->sim_parms) {
00145                 if(tclmd->sim_parms->effector_weights)
00146                         MEM_freeN(tclmd->sim_parms->effector_weights);
00147                 MEM_freeN(tclmd->sim_parms);
00148         }
00149 
00150         if(tclmd->coll_parms)
00151                 MEM_freeN(tclmd->coll_parms);
00152         
00153         BKE_ptcache_free_list(&tclmd->ptcaches);
00154         tclmd->point_cache = NULL;
00155 
00156         tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms);
00157         if(clmd->sim_parms->effector_weights)
00158                 tclmd->sim_parms->effector_weights = MEM_dupallocN(clmd->sim_parms->effector_weights);
00159         tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
00160         tclmd->point_cache = BKE_ptcache_copy_list(&tclmd->ptcaches, &clmd->ptcaches);
00161         tclmd->clothObject = NULL;
00162 }
00163 
00164 static int dependsOnTime(ModifierData *UNUSED(md))
00165 {
00166         return 1;
00167 }
00168 
00169 static void freeData(ModifierData *md)
00170 {
00171         ClothModifierData *clmd = (ClothModifierData*) md;
00172         
00173         if (clmd) 
00174         {
00175                 if(G.rt > 0)
00176                         printf("clothModifier_freeData\n");
00177                 
00178                 cloth_free_modifier_extern (clmd);
00179                 
00180                 if(clmd->sim_parms) {
00181                         if(clmd->sim_parms->effector_weights)
00182                                 MEM_freeN(clmd->sim_parms->effector_weights);
00183                         MEM_freeN(clmd->sim_parms);
00184                 }
00185                 if(clmd->coll_parms)
00186                         MEM_freeN(clmd->coll_parms);    
00187                 
00188                 BKE_ptcache_free_list(&clmd->ptcaches);
00189                 clmd->point_cache = NULL;
00190         }
00191 }
00192 
00193 static void foreachIDLink(ModifierData *md, Object *ob,
00194                                            IDWalkFunc walk, void *userData)
00195 {
00196         ClothModifierData *clmd = (ClothModifierData*) md;
00197 
00198         if(clmd->coll_parms) {
00199                 walk(userData, ob, (ID **)&clmd->coll_parms->group);
00200         }
00201 
00202         if(clmd->sim_parms && clmd->sim_parms->effector_weights) {
00203                 walk(userData, ob, (ID **)&clmd->sim_parms->effector_weights->group);
00204         }
00205 }
00206 
00207 ModifierTypeInfo modifierType_Cloth = {
00208         /* name */              "Cloth",
00209         /* structName */        "ClothModifierData",
00210         /* structSize */        sizeof(ClothModifierData),
00211         /* type */              eModifierTypeType_Nonconstructive,
00212         /* flags */             eModifierTypeFlag_AcceptsMesh
00213                                                         | eModifierTypeFlag_UsesPointCache
00214                                                         | eModifierTypeFlag_Single,
00215 
00216         /* copyData */          copyData,
00217         /* deformVerts */       NULL,
00218         /* deformMatrices */    NULL,
00219         /* deformVertsEM */     NULL,
00220         /* deformMatricesEM */  NULL,
00221         /* applyModifier */     applyModifier,
00222         /* applyModifierEM */   NULL,
00223         /* initData */          initData,
00224         /* requiredDataMask */  requiredDataMask,
00225         /* freeData */          freeData,
00226         /* isDisabled */        NULL,
00227         /* updateDepgraph */    updateDepgraph,
00228         /* dependsOnTime */     dependsOnTime,
00229         /* dependsOnNormals */  NULL,
00230         /* foreachObjectLink */ NULL,
00231         /* foreachIDLink */     foreachIDLink,
00232 };