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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/modifier.c')
-rw-r--r--source/blender/blenkernel/intern/modifier.c311
1 files changed, 311 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 50c6705c6b6..d552fdad5c2 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -53,6 +53,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_armature_types.h"
+#include "DNA_cloth_types.h"
#include "DNA_effect_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
@@ -74,6 +75,7 @@
#include "BKE_main.h"
#include "BKE_anim.h"
#include "BKE_bad_level_calls.h"
+#include "BKE_cloth.h"
#include "BKE_curve.h"
#include "BKE_customdata.h"
#include "BKE_global.h"
@@ -88,6 +90,7 @@
#include "BKE_object.h"
#include "BKE_mesh.h"
#include "BKE_softbody.h"
+#include "BKE_cloth.h"
#include "BKE_material.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
@@ -4942,6 +4945,282 @@ static void softbodyModifier_deformVerts(
sbObjectStep(ob, (float)G.scene->r.cfra, vertexCos, numVerts);
}
+
+/* Cloth */
+
+static void clothModifier_initData(ModifierData *md)
+{
+ ClothModifierData *clmd = (ClothModifierData*) md;
+
+ clmd->sim_parms = MEM_callocN(sizeof(SimulationSettings), "cloth sim parms");
+ clmd->coll_parms = MEM_callocN(sizeof(CollisionSettings), "cloth coll parms");
+
+ /* check for alloc failing */
+ if(!clmd->sim_parms || !clmd->coll_parms)
+ return;
+
+ cloth_init (clmd);
+ printf("clothModifier_initData\n");
+}
+
+static DerivedMesh *clothModifier_applyModifier(ModifierData *md, Object *ob,
+ DerivedMesh *derivedData, int useRenderParams, int isFinalCalc)
+{
+ ClothModifierData *clmd = (ClothModifierData*) md;
+ DerivedMesh *result=NULL;
+
+ /* check for alloc failing */
+ if(!clmd->sim_parms || !clmd->coll_parms)
+ return derivedData;
+
+ result = clothModifier_do(clmd, ob, derivedData, useRenderParams, isFinalCalc);
+
+ if(result)
+ {
+ CDDM_calc_normals(result);
+ return result;
+ }
+ return derivedData;
+}
+
+static void clothModifier_updateDepgraph(
+ ModifierData *md, DagForest *forest, Object *ob,
+ DagNode *obNode)
+{
+ ClothModifierData *clmd = (ClothModifierData*) md;
+
+ Base *base;
+
+ if(clmd)
+ {
+ for(base = G.scene->base.first; base; base= base->next)
+ {
+ Object *ob1= base->object;
+ if(ob1 != ob)
+ {
+ CollisionModifierData *coll_clmd = (CollisionModifierData *)modifiers_findByType(ob1, eModifierType_Collision);
+ if(coll_clmd)
+ {
+ DagNode *curNode = dag_get_node(forest, ob1);
+ dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
+ }
+ }
+ }
+ }
+}
+
+CustomDataMask clothModifier_requiredDataMask(ModifierData *md)
+{
+ ClothModifierData *clmd = (ClothModifierData *)md;
+ CustomDataMask dataMask = 0;
+
+ /* ask for vertexgroups if we need them */
+ if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
+ if (clmd->sim_parms->vgroup_mass > 0)
+ dataMask |= (1 << CD_MDEFORMVERT);
+
+ return dataMask;
+}
+
+static void clothModifier_copyData(ModifierData *md, ModifierData *target)
+{
+ ClothModifierData *clmd = (ClothModifierData*) md;
+ ClothModifierData *tclmd = (ClothModifierData*) target;
+
+ if(tclmd->sim_parms)
+ MEM_freeN(tclmd->sim_parms);
+ if(tclmd->coll_parms)
+ MEM_freeN(tclmd->coll_parms);
+
+ tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms);
+ tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
+
+ tclmd->sim_parms->lastcachedframe = 0;
+}
+
+
+static int clothModifier_dependsOnTime(ModifierData *md)
+{
+ return 1;
+}
+
+static void clothModifier_freeData(ModifierData *md)
+{
+ ClothModifierData *clmd = (ClothModifierData*) md;
+
+ if (clmd)
+ {
+ if(G.rt > 0)
+ printf("clothModifier_freeData\n");
+
+ cloth_free_modifier_extern (clmd);
+
+ if(clmd->sim_parms)
+ MEM_freeN(clmd->sim_parms);
+ if(clmd->coll_parms)
+ MEM_freeN(clmd->coll_parms);
+ }
+}
+
+/* Collision */
+
+static void collisionModifier_initData(ModifierData *md)
+{
+ CollisionModifierData *collmd = (CollisionModifierData*) md;
+
+ collmd->x = NULL;
+ collmd->xnew = NULL;
+ collmd->current_x = NULL;
+ collmd->current_xnew = NULL;
+ collmd->current_v = NULL;
+ collmd->time = -1;
+ collmd->numverts = 0;
+ collmd->tree = NULL;
+}
+
+static void collisionModifier_freeData(ModifierData *md)
+{
+ CollisionModifierData *collmd = (CollisionModifierData*) md;
+
+ if (collmd)
+ {
+ if(collmd->tree)
+ bvh_free(collmd->tree);
+ if(collmd->x)
+ MEM_freeN(collmd->x);
+ if(collmd->xnew)
+ MEM_freeN(collmd->xnew);
+ if(collmd->current_x)
+ MEM_freeN(collmd->current_x);
+ if(collmd->current_xnew)
+ MEM_freeN(collmd->current_xnew);
+ if(collmd->current_v)
+ MEM_freeN(collmd->current_v);
+
+ if(collmd->mfaces)
+ MEM_freeN(collmd->mfaces);
+
+ collmd->x = NULL;
+ collmd->xnew = NULL;
+ collmd->current_x = NULL;
+ collmd->current_xnew = NULL;
+ collmd->current_v = NULL;
+ collmd->time = -1;
+ collmd->numverts = 0;
+ collmd->tree = NULL;
+ collmd->mfaces = NULL;
+ }
+}
+
+static int collisionModifier_dependsOnTime(ModifierData *md)
+{
+ return 1;
+}
+
+static void collisionModifier_deformVerts(
+ ModifierData *md, Object *ob, DerivedMesh *derivedData,
+ float (*vertexCos)[3], int numVerts)
+{
+ CollisionModifierData *collmd = (CollisionModifierData*) md;
+ DerivedMesh *dm = NULL;
+ float current_time = 0;
+ unsigned int numverts = 0, i = 0;
+ MVert *tempVert = NULL;
+
+ /* if possible use/create DerivedMesh */
+ if(derivedData) dm = CDDM_copy(derivedData);
+ else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob);
+
+ if(!ob->pd)
+ {
+ printf("collisionModifier_deformVerts: Should not happen!\n");
+ return;
+ }
+
+ if(dm)
+ {
+ CDDM_apply_vert_coords(dm, vertexCos);
+ CDDM_calc_normals(dm);
+
+ current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 );
+
+ // printf("current_time %f, collmd->time %f\n", current_time, collmd->time);
+
+ if(current_time > collmd->time)
+ {
+ numverts = dm->getNumVerts ( dm );
+
+ // check if mesh has changed
+ if(collmd->x && (numverts != collmd->numverts))
+ collisionModifier_freeData((ModifierData *)collmd);
+
+ if(collmd->time == -1) // first time
+ {
+ collmd->x = dm->dupVertArray(dm); // frame start position
+
+ for ( i = 0; i < numverts; i++ )
+ {
+ // we save global positions
+ Mat4MulVecfl ( ob->obmat, collmd->x[i].co );
+ }
+
+ collmd->xnew = MEM_dupallocN(collmd->x); // frame end position
+ collmd->current_x = MEM_dupallocN(collmd->x); // inter-frame
+ collmd->current_xnew = MEM_dupallocN(collmd->x); // inter-frame
+ collmd->current_v = MEM_dupallocN(collmd->x); // inter-frame
+
+ collmd->numverts = numverts;
+
+ collmd->mfaces = dm->dupFaceArray(dm);
+ collmd->numfaces = dm->getNumFaces(dm);
+
+ // TODO: epsilon
+ // create bounding box hierarchy
+ collmd->tree = bvh_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->x, numverts, ob->pd->pdef_sbift);
+ }
+ else if(numverts == collmd->numverts)
+ {
+ // put positions to old positions
+ tempVert = collmd->x;
+ collmd->x = collmd->xnew;
+ collmd->xnew = tempVert;
+
+ memcpy(collmd->xnew, dm->getVertArray(dm), numverts*sizeof(MVert));
+
+ for ( i = 0; i < numverts; i++ )
+ {
+ // we save global positions
+ Mat4MulVecfl ( ob->obmat, collmd->xnew[i].co );
+ }
+
+ memcpy(collmd->current_xnew, collmd->x, numverts*sizeof(MVert));
+ memcpy(collmd->current_x, collmd->x, numverts*sizeof(MVert));
+
+ /* happens on file load (ONLY when i decomment changes in readfile.c */
+ if(!collmd->tree)
+ {
+ collmd->tree = bvh_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sbift);
+ }
+ else
+ {
+ // recalc static bounding boxes
+ bvh_update_from_mvert(collmd->tree, collmd->current_x, numverts, NULL, 0);
+ }
+ }
+
+ collmd->time = current_time;
+ }
+ else
+ {
+ collmd->time = current_time;
+ }
+ }
+
+ if(dm)
+ dm->release(dm);
+}
+
+
/* Boolean */
static void booleanModifier_copyData(ModifierData *md, ModifierData *target)
@@ -6765,6 +7044,31 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti->flags = eModifierTypeFlag_AcceptsCVs
| eModifierTypeFlag_RequiresOriginalData;
mti->deformVerts = softbodyModifier_deformVerts;
+
+ mti = INIT_TYPE(Cloth);
+ mti->type = eModifierTypeType_Nonconstructive;
+ mti->initData = clothModifier_initData;
+ mti->flags = eModifierTypeFlag_AcceptsMesh
+ | eModifierTypeFlag_RequiresOriginalData;
+ // | eModifierTypeFlag_SupportsMapping
+ // | eModifierTypeFlag_SupportsEditmode
+ // | eModifierTypeFlag_EnableInEditmode;
+ mti->dependsOnTime = clothModifier_dependsOnTime;
+ mti->freeData = clothModifier_freeData;
+ mti->requiredDataMask = clothModifier_requiredDataMask;
+ mti->copyData = clothModifier_copyData;
+ mti->applyModifier = clothModifier_applyModifier;
+ mti->updateDepgraph = clothModifier_updateDepgraph;
+
+ mti = INIT_TYPE(Collision);
+ mti->type = eModifierTypeType_OnlyDeform;
+ mti->initData = collisionModifier_initData;
+ mti->flags = eModifierTypeFlag_AcceptsMesh
+ | eModifierTypeFlag_RequiresOriginalData;
+ mti->dependsOnTime = collisionModifier_dependsOnTime;
+ mti->freeData = collisionModifier_freeData;
+ mti->deformVerts = collisionModifier_deformVerts;
+ // mti->copyData = collisionModifier_copyData;
mti = INIT_TYPE(Boolean);
mti->type = eModifierTypeType_Nonconstructive;
@@ -7024,6 +7328,13 @@ int modifiers_isSoftbodyEnabled(Object *ob)
return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
}
+int modifiers_isClothEnabled(Object *ob)
+{
+ ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth);
+
+ return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
+}
+
int modifiers_isParticleEnabled(Object *ob)
{
ModifierData *md = modifiers_findByType(ob, eModifierType_ParticleSystem);