Particle merge: svn merge -r 12653:12664 https://svn.blender.org/svnroot/bf-blender...
authorDaniel Genrich <daniel.genrich@gmx.net>
Mon, 26 Nov 2007 23:11:07 +0000 (23:11 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Mon, 26 Nov 2007 23:11:07 +0000 (23:11 +0000)
16 files changed:
1  2 
source/blender/blenkernel/BKE_cloth.h
source/blender/blenkernel/BKE_modifier.h
source/blender/blenkernel/BKE_pointcache.h
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/include/butspace.h
source/blender/makesdna/DNA_modifier_types.h
source/blender/makesdna/DNA_object_force.h
source/blender/makesdna/intern/makesdna.c
source/blender/src/buttons_editing.c
source/blender/src/buttons_object.c
source/blender/src/editobject.c
source/blender/src/transform_conversions.c
source/blender/src/transform_generics.c

index f83cf0515dfc63638e15ee9e1351aae77e262ed9,0000000000000000000000000000000000000000..5a986119b71b4f70b6633293e1927e81043e003b
mode 100644,000000..100644
--- /dev/null
@@@ -1,271 -1,0 +1,275 @@@
- #include "BKE_customdata.h"
 +/**
 + * BKE_cloth.h
 + *
 + * $Id: BKE_cloth.h,v 1.1 2007/08/01 02:07:27 daniel Exp $
 + *
 + * ***** BEGIN GPL/BL DUAL 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. The Blender
 + * Foundation also sells licenses for use in proprietary software under
 + * the Blender License.  See http://www.blender.org/BL/ for information
 + * about this.
 + *
 + * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 + *
 + * The Original Code is Copyright (C) Blender Foundation.
 + * All rights reserved.
 + *
 + * The Original Code is: all of this file.
 + *
 + * Contributor(s): none yet.
 + *
 + * ***** END GPL/BL DUAL LICENSE BLOCK *****
 + */
 +#ifndef BKE_CLOTH_H
 +#define BKE_CLOTH_H
 +
++#include "BKE_customdata.h"
 +#include "BLI_linklist.h"
 +#include "BKE_DerivedMesh.h"
++#include "BKE_object.h"
++
++#include "DNA_cloth_types.h"
 +#include "DNA_customdata_types.h"
- void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr);
- void cloth_free_modifier ( ClothModifierData *clmd );
 +#include "DNA_meshdata_types.h"
 +
 +struct Object;
 +struct Cloth;
 +struct MFace;
 +struct DerivedMesh;
++struct ClothModifierData;
 +
 +// this is needed for inlining behaviour
 +
 +#ifndef _WIN32
 +#define LINUX
 +#define DO_INLINE inline
 +#else
 +#define DO_INLINE
 +#endif
 +
 +#define CLOTH_MAX_THREAD 2
 +
 +
 +typedef struct ClothVertex {
 +      int     flags;          /* General flags per vertex.            */
 +      float   mass;           /* mass / weight of the vertex          */
 +      float   goal;           /* goal, from SB                        */
 +      float   impulse[3];     /* used in collision.c */
 +      unsigned int impulse_count; /* same as above */
 +      float collball;
 +} ClothVertex;
 +
 +typedef struct ClothSpring {
 +      int     ij;             /* Pij from the paper, one end of the spring.   */
 +      int     kl;             /* Pkl from the paper, one end of the spring.   */
 +      float   restlen;        /* The original length of the spring.   */
 +      int     matrix_index;   /* needed for implicit solver (fast lookup) */
 +      int     type;           /* types defined in BKE_cloth.h ("springType") */
 +      int     flags;          /* defined in BKE_cloth.h, e.g. deactivated due to tearing */
 +      float dfdx[3][3];
 +      float dfdv[3][3];
 +      float f[3];
 +} ClothSpring;
 +
 +typedef struct Cloth {
 +      struct ClothVertex      *verts;                 /* The vertices that represent this cloth. */
 +      struct LinkNode         *springs;               /* The springs connecting the mesh. */
 +      struct BVH              *tree;          /* collision tree for this cloth object */
 +      struct BVH              *selftree;              /* self collision tree for this cloth object */
 +      struct MFace            *mfaces;
 +      struct Implicit_Data    *implicit;      /* our implicit solver connects to this pointer */
 +      struct EdgeHash         *edgehash; /* used for fast checking adjacent points */
 +      unsigned int            numverts;               /* The number of verts == m * n. */
 +      unsigned int            numsprings;             /* The count of springs. */
 +      unsigned int            numfaces;
 +      unsigned int            numothersprings;
 +      unsigned int            numspringssave;
 +      unsigned int            old_solver_type;
 +      float                   (*x)[3]; /* The current position of all vertices.*/
 +      float                   (*xold)[3]; /* The previous position of all vertices.*/
 +      float                   (*current_x)[3]; /* The TEMPORARY current position of all vertices.*/
 +      float                   (*current_xold)[3]; /* The TEMPORARY previous position of all vertices.*/
 +      float                   (*v)[4]; /* the current velocity of all vertices */
 +      float                   (*current_v)[3];
 +      float                   (*xconst)[3];
 +} Cloth;
 +
 +/* goal defines */
 +#define SOFTGOALSNAP  0.999f
 +
 +/* This is approximately the smallest number that can be
 +* represented by a float, given its precision. */
 +#define ALMOST_ZERO           0.000001
 +
 +// some macro enhancements for vector treatment
 +#define VECADDADD(v1,v2,v3)   {*(v1)+= *(v2) + *(v3); *(v1+1)+= *(v2+1) + *(v3+1); *(v1+2)+= *(v2+2) + *(v3+2);}
 +#define VECSUBADD(v1,v2,v3)   {*(v1)-= *(v2) + *(v3); *(v1+1)-= *(v2+1) + *(v3+1); *(v1+2)-= *(v2+2) + *(v3+2);}
 +#define VECADDSUB(v1,v2,v3)   {*(v1)+= *(v2) - *(v3); *(v1+1)+= *(v2+1) - *(v3+1); *(v1+2)+= *(v2+2) - *(v3+2);}
 +#define VECSUBADDSS(v1,v2,aS,v3,bS)   {*(v1)-= *(v2)*aS + *(v3)*bS; *(v1+1)-= *(v2+1)*aS + *(v3+1)*bS; *(v1+2)-= *(v2+2)*aS + *(v3+2)*bS;}
 +#define VECADDSUBSS(v1,v2,aS,v3,bS)   {*(v1)+= *(v2)*aS - *(v3)*bS; *(v1+1)+= *(v2+1)*aS - *(v3+1)*bS; *(v1+2)+= *(v2+2)*aS - *(v3+2)*bS;}
 +#define VECADDSS(v1,v2,aS,v3,bS)      {*(v1)= *(v2)*aS + *(v3)*bS; *(v1+1)= *(v2+1)*aS + *(v3+1)*bS; *(v1+2)= *(v2+2)*aS + *(v3+2)*bS;}
 +#define VECADDS(v1,v2,v3,bS)  {*(v1)= *(v2) + *(v3)*bS; *(v1+1)= *(v2+1) + *(v3+1)*bS; *(v1+2)= *(v2+2) + *(v3+2)*bS;}
 +#define VECSUBMUL(v1,v2,aS)   {*(v1)-= *(v2) * aS; *(v1+1)-= *(v2+1) * aS; *(v1+2)-= *(v2+2) * aS;}
 +#define VECSUBS(v1,v2,v3,bS)  {*(v1)= *(v2) - *(v3)*bS; *(v1+1)= *(v2+1) - *(v3+1)*bS; *(v1+2)= *(v2+2) - *(v3+2)*bS;}
 +#define VECSUBSB(v1,v2, v3,bS)        {*(v1)= (*(v2)- *(v3))*bS; *(v1+1)= (*(v2+1) - *(v3+1))*bS; *(v1+2)= (*(v2+2) - *(v3+2))*bS;}
 +#define VECMULS(v1,aS)        {*(v1)*= aS; *(v1+1)*= aS; *(v1+2)*= *aS;}
 +#define VECADDMUL(v1,v2,aS)   {*(v1)+= *(v2) * aS; *(v1+1)+= *(v2+1) * aS; *(v1+2)+= *(v2+2) * aS;}
 +
 +/* SIMULATION FLAGS: goal flags,.. */
 +/* These are the bits used in SimSettings.flags. */
 +typedef enum
 +{
 +    CLOTH_SIMSETTINGS_FLAG_RESET = ( 1 << 1 ),                // The CM object requires a reinitializaiton.
 +    CLOTH_SIMSETTINGS_FLAG_COLLOBJ = ( 1 << 2 ),      // object is only collision object, no cloth simulation is done
 +    CLOTH_SIMSETTINGS_FLAG_GOAL = ( 1 << 3 ),                 // we have goals enabled
 +    CLOTH_SIMSETTINGS_FLAG_TEARING = ( 1 << 4 ), // true if tearing is enabled
 +    CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT = ( 1 << 5 ),
 +    CLOTH_SIMSETTINGS_FLAG_BIG_FORCE = ( 1 << 6 ), // true if we have big spring force for bending
 +    CLOTH_SIMSETTINGS_FLAG_SLEEP = ( 1 << 7 ), // true if we let the cloth go to sleep
 +} CLOTH_SIMSETTINGS_FLAGS;
 +
 +/* SPRING FLAGS */
 +typedef enum
 +{
 +    CLOTH_COLLISIONSETTINGS_FLAG_ENABLED = ( 1 << 1 ),
 +} CLOTH_COLLISIONSETTINGS_FLAGS;
 +
 +/* Spring types as defined in the paper.*/
 +typedef enum
 +{
 +    CLOTH_SPRING_TYPE_STRUCTURAL = 0,
 +    CLOTH_SPRING_TYPE_SHEAR,
 +    CLOTH_SPRING_TYPE_BENDING,
 +} CLOTH_SPRING_TYPES;
 +
 +/* SPRING FLAGS */
 +typedef enum
 +{
 +    CLOTH_SPRING_FLAG_DEACTIVATE = ( 1 << 1 ),
 +    CLOTH_SPRING_FLAG_NEEDED = ( 1 << 2 ), // springs has values to be applied
 +} CLOTH_SPRINGS_FLAGS;
 +
 +/* Bits to or into the ClothVertex.flags. */
 +#define CVERT_FLAG_PINNED     1
 +#define CVERT_FLAG_COLLISION  2
 +
 +
 +// needed for buttons_object.c
- void implicit_set_positions ( ClothModifierData *clmd );
++void cloth_clear_cache(struct Object *ob, struct ClothModifierData *clmd, float framenr);
++void cloth_free_modifier ( struct ClothModifierData *clmd );
 +
 +// needed for cloth.c
- DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc);
++void implicit_set_positions ( struct ClothModifierData *clmd );
 +
 +// from cloth.c, needed for modifier.c
- int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep, float dt);
++DerivedMesh *clothModifier_do(struct ClothModifierData *clmd, struct Object *ob, struct DerivedMesh *dm, int useRenderParams, int isFinalCalc);
 +
 +// needed in implicit.c
- void cloth_free_modifier ( ClothModifierData *clmd );
- void cloth_init ( ClothModifierData *clmd );
++int cloth_bvh_objcollision(struct ClothModifierData *clmd, float step, float prevstep, float dt);
 +
 +////////////////////////////////////////////////
 +
 +
 +/////////////////////////////////////////////////
 +// cloth.c
 +////////////////////////////////////////////////
- typedef void ( *CM_COLLISION_SELF ) ( ClothModifierData *clmd, int step );
++void cloth_free_modifier ( struct ClothModifierData *clmd );
++void cloth_init ( struct ClothModifierData *clmd );
 +////////////////////////////////////////////////
 +
 +
 +/* Typedefs for function pointers we need for solvers and collision detection. */
-       int     ( *init ) ( Object *ob, ClothModifierData *clmd );
-       int     ( *solver ) ( Object *ob, float framenr, ClothModifierData *clmd, ListBase *effectors );
-       int     ( *free ) ( ClothModifierData *clmd );
++typedef void ( *CM_COLLISION_SELF ) ( struct ClothModifierData *clmd, int step );
 +// typedef void ( *CM_COLLISION_OBJ ) ( ClothModifierData *clmd, int step, CM_COLLISION_RESPONSE collision_response );
 +
 +
 +/* This enum provides the IDs for our solvers. */
 +// only one available in the moment
 +typedef enum {
 +    CM_IMPLICIT = 0,
 +    CM_VERLET = 1,
 +} CM_SOLVER_ID;
 +
 +
 +/* This structure defines how to call the solver.
 +*/
 +typedef struct
 +{
 +      char            *name;
 +      CM_SOLVER_ID    id;
- int implicit_init ( Object *ob, ClothModifierData *clmd );
- int implicit_free ( ClothModifierData *clmd );
- int implicit_solver ( Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors );
++      int     ( *init ) ( struct Object *ob, struct ClothModifierData *clmd );
++      int     ( *solver ) ( struct Object *ob, float framenr, struct ClothModifierData *clmd, struct ListBase *effectors );
++      int     ( *free ) ( struct ClothModifierData *clmd );
 +}
 +CM_SOLVER_DEF;
 +
 +
 +/* new C implicit simulator */
- int verlet_init ( Object *ob, ClothModifierData *clmd );
- int verlet_free ( ClothModifierData *clmd );
- int verlet_solver ( Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors );
++int implicit_init ( struct Object *ob, struct ClothModifierData *clmd );
++int implicit_free ( struct ClothModifierData *clmd );
++int implicit_solver ( struct Object *ob, float frame, struct ClothModifierData *clmd, struct ListBase *effectors );
 +
 +/* explicit verlet simulator */
++int verlet_init ( struct Object *ob, struct ClothModifierData *clmd );
++int verlet_free ( struct ClothModifierData *clmd );
++int verlet_solver ( struct Object *ob, float frame, struct ClothModifierData *clmd, struct ListBase *effectors );
 +
 +
 +/* used for collisions in collision.c */
 +/*
 +typedef struct CollPair
 +{
 +      unsigned int face1; // cloth face
 +      unsigned int face2; // object face
 +      double distance; // magnitude of vector
 +      float normal[3];
 +      float vector[3]; // unnormalized collision vector: p2-p1
 +      float pa[3], pb[3]; // collision point p1 on face1, p2 on face2
 +      int lastsign; // indicates if the distance sign has changed, unused itm
 +      float time; // collision time, from 0 up to 1
 +      unsigned int ap1, ap2, ap3, bp1, bp2, bp3, bp4;
 +      unsigned int pointsb[4];
 +}
 +CollPair;
 +*/
 +
 +/* used for collisions in collision.c */
 +typedef struct EdgeCollPair
 +{
 +      unsigned int p11, p12, p21, p22;
 +      float normal[3];
 +      float vector[3];
 +      float time;
 +      int lastsign;
 +      float pa[3], pb[3]; // collision point p1 on face1, p2 on face2
 +}
 +EdgeCollPair;
 +
 +/* used for collisions in collision.c */
 +typedef struct FaceCollPair
 +{
 +      unsigned int p11, p12, p13, p21;
 +      float normal[3];
 +      float vector[3];
 +      float time;
 +      int lastsign;
 +      float pa[3], pb[3]; // collision point p1 on face1, p2 on face2
 +}
 +FaceCollPair;
 +
 +// function definitions from implicit.c
 +DO_INLINE void mul_fvector_S(float to[3], float from[3], float scalar);
 +
 +#endif
 +
index 644c3dd32f40db36ceb8c8e4eb56a822007ea8ad,24da941db905bf2064b08795d0dbd5a46e82d819..48e083bbf9b47f322171690d47cd40f8513ea124
@@@ -277,7 -283,7 +283,9 @@@ int           modifiers_getCageIndex(st
                                       int *lastPossibleCageIndex_r);
  
  int           modifiers_isSoftbodyEnabled(struct Object *ob);
 +struct ClothModifierData *modifiers_isClothEnabled(Object *ob);
+ int           modifiers_isParticleEnabled(struct Object *ob);
++
  struct Object *modifiers_isDeformedByArmature(struct Object *ob);
  struct Object *modifiers_isDeformedByLattice(struct Object *ob);
  int           modifiers_usesArmature(struct Object *ob, struct bArmature *arm);
index 9359177b4e926e23aafd1d45c683f3ccb1e22037,46d240a41833a2e54d1b40daea3774e15c1038e7..020b9d15417a3f9a2cd4b457e8872eb0ef119985
  
  #include "DNA_ID.h"
  
- #define PTCache_EXT ".bphys"
- #define PTCache_PATH "//pointcache/"
+ /* options for clearing pointcache - used for BKE_ptcache_id_clear
+  Before and after are non inclusive (they wont remove the cfra) */
+ #define PTCACHE_CLEAR_ALL             0
+ #define PTCACHE_CLEAR_FRAME           1
+ #define PTCACHE_CLEAR_BEFORE  2
+ #define PTCACHE_CLEAR_AFTER           3
  
- int           PTCache_id_filename(struct ID *id, char *filename, int cfra, int stack_index, short do_path, short do_ext);
- FILE *        PTCache_id_fopen(struct ID *id, char mode, int cfra, int stack_index);
- void  PTCache_id_clear(struct ID *id, int cfra, int stack_index);
+ #define PTCACHE_EXT ".bphys"
+ #define PTCACHE_PATH "//pointcache/"
 -int           BKE_ptcache_id_filename(struct ID *id, char *filename, int cfra, int stack_index, short do_path, short do_ext);
++int   BKE_ptcache_id_filename(struct ID *id, char *filename, int cfra, int stack_index, short do_path, short do_ext);
+ FILE *        BKE_ptcache_id_fopen(struct ID *id, char mode, int cfra, int stack_index);
+ void  BKE_ptcache_id_clear(struct ID *id, char mode, int cfra, int stack_index);
  
  #endif
index 436a14d1d6c8888a5f5166b430e5e1aedc1d7618,0000000000000000000000000000000000000000..b997049a637ec47d19e4f1efa8948997bf47da66
mode 100644,000000..100644
--- /dev/null
@@@ -1,1189 -1,0 +1,1213 @@@
-               PTCache_id_clear((ID *)ob, framenr, stack_index);
 +/*  cloth.c
 +*
 +*
 +* ***** BEGIN GPL/BL DUAL 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. The Blender
 +* Foundation also sells licenses for use in proprietary software under
 +* the Blender License.  See http://www.blender.org/BL/ for information
 +* about this.
 +*
 +* 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 +*
 +* The Original Code is Copyright (C) Blender Foundation
 +* All rights reserved.
 +*
 +* The Original Code is: all of this file.
 +*
 +* Contributor(s): none yet.
 +*
 +* ***** END GPL/BL DUAL LICENSE BLOCK *****
 +*/
 +
 +
 +#include <math.h>
 +#include <stdlib.h>
 +#include <string.h>
 +
 +#include "MEM_guardedalloc.h"
 +
 +/* types */
 +#include "DNA_curve_types.h"
 +#include "DNA_cloth_types.h"
 +#include "DNA_object_types.h"
 +#include "DNA_object_force.h"
 +#include "DNA_key_types.h"
 +#include "DNA_lattice_types.h"
 +#include "DNA_mesh_types.h"
 +#include "DNA_meshdata_types.h"
 +#include "DNA_modifier_types.h"
 +#include "DNA_scene_types.h"
 +
 +#include "BLI_blenlib.h"
 +#include "BLI_arithb.h"
 +#include "BLI_edgehash.h"
 +#include "BLI_linklist.h"
 +
 +#include "BKE_curve.h"
 +#include "BKE_cloth.h"
 +#include "BKE_collisions.h"
 +#include "BKE_deform.h"
 +#include "BKE_DerivedMesh.h"
 +#include "BKE_cdderivedmesh.h"
 +#include "BKE_displist.h"
 +#include "BKE_effect.h"
 +#include "BKE_global.h"
 +#include "BKE_key.h"
 +#include "BKE_mesh.h"
 +#include "BKE_modifier.h"
 +#include "BKE_object.h"
 +#include "BKE_pointcache.h"
 +#include "BKE_utildefines.h"
 +
 +#include "BIF_editdeform.h"
 +#include "BIF_editkey.h"
 +#include "DNA_screen_types.h"
 +#include "BSE_headerbuttons.h"
 +#include "BIF_screen.h"
 +#include "BIF_space.h"
 +#include "mydevice.h"
 +
 +#ifdef _WIN32
 +void tstart ( void )
 +{}
 +void tend ( void )
 +{
 +}
 +double tval()
 +{
 +      return 0;
 +}
 +#else
 +#include <sys/time.h>
 +                       static struct timeval _tstart, _tend;
 +       static struct timezone tz;
 +       void tstart ( void )
 +{
 +      gettimeofday ( &_tstart, &tz );
 +}
 +void tend ( void )
 +{
 +      gettimeofday ( &_tend,&tz );
 +}
 +double tval()
 +{
 +      double t1, t2;
 +      t1 = ( double ) _tstart.tv_sec + ( double ) _tstart.tv_usec/ ( 1000*1000 );
 +      t2 = ( double ) _tend.tv_sec + ( double ) _tend.tv_usec/ ( 1000*1000 );
 +      return t2-t1;
 +}
 +#endif
 +
 +/* Our available solvers. */
 +// 255 is the magic reserved number, so NEVER try to put 255 solvers in here!
 +// 254 = MAX!
 +static CM_SOLVER_DEF solvers [] =
 +{
 +      { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free },
 +      // { "Verlet", CM_VERLET, verlet_init, verlet_solver, verlet_free },
 +};
 +
 +/* ********** cloth engine ******* */
 +/* Prototypes for internal functions.
 +*/
 +static void cloth_to_object (Object *ob,  DerivedMesh *dm, ClothModifierData *clmd);
 +static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr);
 +static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, DerivedMesh *olddm, float framenr);
 +
 +int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm );
 +static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup);
 +/******************************************************************************
 +*
 +* External interface called by modifier.c clothModifier functions.
 +*
 +******************************************************************************/
 +/**
 + * cloth_init -  creates a new cloth simulation.
 + *
 + * 1. create object
 + * 2. fill object with standard values or with the GUI settings if given 
 + */
 +void cloth_init (ClothModifierData *clmd)
 +{
 +      /* Initialize our new data structure to reasonable values. */
 +      clmd->sim_parms->gravity [0] = 0.0;
 +      clmd->sim_parms->gravity [1] = 0.0;
 +      clmd->sim_parms->gravity [2] = -9.81;
 +      clmd->sim_parms->structural = 100.0;
 +      clmd->sim_parms->shear = 100.0;
 +      clmd->sim_parms->bending = 1.0;
 +      clmd->sim_parms->Cdis = 5.0;
 +      clmd->sim_parms->Cvi = 1.0;
 +      clmd->sim_parms->mass = 1.0f;
 +      clmd->sim_parms->stepsPerFrame = 5;
 +      clmd->sim_parms->sim_time = 1.0;
 +      clmd->sim_parms->flags = CLOTH_SIMSETTINGS_FLAG_RESET;
 +      clmd->sim_parms->solver_type = 0; 
 +      clmd->sim_parms->preroll = 0;
 +      clmd->sim_parms->maxspringlen = 10;
 +      clmd->coll_parms->self_friction = 5.0;
 +      clmd->coll_parms->friction = 10.0;
 +      clmd->coll_parms->loop_count = 1;
 +      clmd->coll_parms->epsilon = 0.01;
 +      clmd->coll_parms->selfepsilon = 0.1;
 +      
 +      /* These defaults are copied from softbody.c's
 +      * softbody_calc_forces() function.
 +      */
 +      clmd->sim_parms->eff_force_scale = 1000.0;
 +      clmd->sim_parms->eff_wind_scale = 250.0;
 +
 +      // also from softbodies
 +      clmd->sim_parms->maxgoal = 1.0;
 +      clmd->sim_parms->mingoal = 0.0;
 +      clmd->sim_parms->defgoal = 0.0;
 +      clmd->sim_parms->goalspring = 100.0;
 +      clmd->sim_parms->goalfrict = 0.0;
 +}
 +
 +// unused in the moment, cloth needs quads from mesh
 +DerivedMesh *CDDM_convert_to_triangle(DerivedMesh *dm)
 +{
 +      /*
 +      DerivedMesh *result = NULL;
 +      int i;
 +      int numverts = dm->getNumVerts(dm);
 +      int numedges = dm->getNumEdges(dm);
 +      int numfaces = dm->getNumFaces(dm);
 +
 +      MVert *mvert = CDDM_get_verts(dm);
 +      MEdge *medge = CDDM_get_edges(dm);
 +      MFace *mface = CDDM_get_faces(dm);
 +
 +      MVert *mvert2;
 +      MFace *mface2;
 +      unsigned int numtris=0;
 +      unsigned int numquads=0;
 +      int a = 0;
 +      int random = 0;
 +      int firsttime = 0;
 +      float vec1[3], vec2[3], vec3[3], vec4[3], vec5[3];
 +      float mag1=0, mag2=0;
 +
 +      for(i = 0; i < numfaces; i++)
 +      {
 +      if(mface[i].v4)
 +      numquads++;
 +      else
 +      numtris++;      
 +}
 +
 +      result = CDDM_from_template(dm, numverts, 0, numtris + 2*numquads);
 +
 +      if(!result)
 +      return NULL;
 +
 +      // do verts
 +      mvert2 = CDDM_get_verts(result);
 +      for(a=0; a<numverts; a++) 
 +      {
 +      MVert *inMV;
 +      MVert *mv = &mvert2[a];
 +
 +      inMV = &mvert[a];
 +
 +      DM_copy_vert_data(dm, result, a, a, 1);
 +      *mv = *inMV;
 +}
 +
 +
 +      // do faces
 +      mface2 = CDDM_get_faces(result);
 +      for(a=0, i=0; a<numfaces; a++) 
 +      {
 +      MFace *mf = &mface2[i];
 +      MFace *inMF;
 +      inMF = &mface[a];
 +
 +              
 +              // DM_copy_face_data(dm, result, a, i, 1);
 +
 +              // *mf = *inMF;
 +              
 +
 +      if(mface[a].v4 && random==1)
 +      {
 +      mf->v1 = mface[a].v2;
 +      mf->v2 = mface[a].v3;
 +      mf->v3 = mface[a].v4;
 +}
 +      else
 +      {
 +      mf->v1 = mface[a].v1;
 +      mf->v2 = mface[a].v2;
 +      mf->v3 = mface[a].v3;
 +}
 +
 +      mf->v4 = 0;
 +      mf->flag |= ME_SMOOTH;
 +
 +      test_index_face(mf, NULL, 0, 3);
 +
 +      if(mface[a].v4)
 +      {
 +      MFace *mf2;
 +
 +      i++;
 +
 +      mf2 = &mface2[i];
 +                      
 +                      // DM_copy_face_data(dm, result, a, i, 1);
 +
 +                      // *mf2 = *inMF;
 +                      
 +
 +      if(random==1)
 +      {
 +      mf2->v1 = mface[a].v1;
 +      mf2->v2 = mface[a].v2;
 +      mf2->v3 = mface[a].v4;
 +}
 +      else
 +      {
 +      mf2->v1 = mface[a].v4;
 +      mf2->v2 = mface[a].v1;
 +      mf2->v3 = mface[a].v3;
 +}
 +      mf2->v4 = 0;
 +      mf2->flag |= ME_SMOOTH;
 +
 +      test_index_face(mf2, NULL, 0, 3);
 +}
 +
 +      i++;
 +}
 +
 +      CDDM_calc_edges(result);
 +      CDDM_calc_normals(result);
 +
 +      return result;
 +      */
 +      
 +      return NULL;
 +}
 +
 +
 +DerivedMesh *CDDM_create_tearing(ClothModifierData *clmd, DerivedMesh *dm)
 +{
 +      /*
 +      DerivedMesh *result = NULL;
 +      unsigned int i = 0, a = 0, j=0;
 +      int numverts = dm->getNumVerts(dm);
 +      int numedges = dm->getNumEdges(dm);
 +      int numfaces = dm->getNumFaces(dm);
 +
 +      MVert *mvert = CDDM_get_verts(dm);
 +      MEdge *medge = CDDM_get_edges(dm);
 +      MFace *mface = CDDM_get_faces(dm);
 +
 +      MVert *mvert2;
 +      MFace *mface2;
 +      unsigned int numtris=0;
 +      unsigned int numquads=0;
 +      EdgeHash *edgehash = NULL;
 +      Cloth *cloth = clmd->clothObject;
 +      ClothSpring *springs = cloth->springs;
 +      unsigned int numsprings = cloth->numsprings;
 +      
 +      // create spring tearing hash
 +      edgehash = BLI_edgehash_new();
 +      
 +      for(i = 0; i < numsprings; i++)
 +      {
 +      if((springs[i].flags & CSPRING_FLAG_DEACTIVATE)
 +      &&(!BLI_edgehash_haskey(edgehash, springs[i].ij, springs[i].kl)))
 +      {
 +      BLI_edgehash_insert(edgehash, springs[i].ij, springs[i].kl, NULL);
 +      BLI_edgehash_insert(edgehash, springs[i].kl, springs[i].ij, NULL);
 +      j++;
 +}
 +}
 +      
 +      // printf("found %d tears\n", j);
 +      
 +      result = CDDM_from_template(dm, numverts, 0, numfaces);
 +
 +      if(!result)
 +      return NULL;
 +
 +      // do verts
 +      mvert2 = CDDM_get_verts(result);
 +      for(a=0; a<numverts; a++) 
 +      {
 +      MVert *inMV;
 +      MVert *mv = &mvert2[a];
 +
 +      inMV = &mvert[a];
 +
 +      DM_copy_vert_data(dm, result, a, a, 1);
 +      *mv = *inMV;
 +}
 +
 +
 +      // do faces
 +      mface2 = CDDM_get_faces(result);
 +      for(a=0, i=0; a<numfaces; a++) 
 +      {
 +      MFace *mf = &mface2[i];
 +      MFace *inMF;
 +      inMF = &mface[a];
 +
 +              
 +              // DM_copy_face_data(dm, result, a, i, 1);
 +
 +              // *mf = *inMF;
 +              
 +              
 +      if((!BLI_edgehash_haskey(edgehash, mface[a].v1, mface[a].v2))
 +      &&(!BLI_edgehash_haskey(edgehash, mface[a].v2, mface[a].v3))
 +      &&(!BLI_edgehash_haskey(edgehash, mface[a].v3, mface[a].v4))
 +      &&(!BLI_edgehash_haskey(edgehash, mface[a].v4, mface[a].v1)))
 +      {
 +      mf->v1 = mface[a].v1;
 +      mf->v2 = mface[a].v2;
 +      mf->v3 = mface[a].v3;
 +      mf->v4 = mface[a].v4;
 +      
 +      test_index_face(mf, NULL, 0, 4);
 +      
 +      i++;
 +}
 +}
 +
 +      CDDM_lower_num_faces(result, i);
 +      CDDM_calc_edges(result);
 +      CDDM_calc_normals(result);
 +      
 +      BLI_edgehash_free(edgehash, NULL);
 +
 +      return result;
 +      */
 +      
 +      return NULL;
 +}
 +
 +int modifiers_indexInObject(Object *ob, ModifierData *md_seek);
 +
 +void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
 +{
 +      int stack_index = -1;
 +      
 +      if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT))
 +      {
 +              stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
 +              
-       fp = PTCache_id_fopen((ID *)ob, 'w', framenr, stack_index);
++              BKE_ptcache_id_clear((ID *)ob, PTCACHE_CLEAR_AFTER, framenr, stack_index);
 +      }
 +}
 +static void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr)
 +{
 +      FILE *fp = NULL;
 +      int stack_index = -1;
 +      unsigned int a;
 +      Cloth *cloth = clmd->clothObject;
 +      
 +      if(!cloth)
 +              return;
 +      
 +      stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
 +      
-       fp = PTCache_id_fopen((ID *)ob, 'r', framenr, stack_index);
++      fp = BKE_ptcache_id_fopen((ID *)ob, 'w', framenr, stack_index);
 +      if(!fp) return;
 +      
 +      for(a = 0; a < cloth->numverts; a++)
 +      {
 +              fwrite(&cloth->x[a], sizeof(float),4,fp);
 +              fwrite(&cloth->xconst[a], sizeof(float),4,fp);
 +              fwrite(&cloth->v[a], sizeof(float),4,fp);
 +      }
 +      
 +      fclose(fp);
 +}
 +static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr)
 +{
 +      FILE *fp = NULL;
 +      int stack_index = -1;
 +      unsigned int a, ret = 1;
 +      Cloth *cloth = clmd->clothObject;
 +      
 +      if(!cloth)
 +              return 0;
 +      
 +      stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
 +      
-       unsigned int i = 0;
++      fp = BKE_ptcache_id_fopen((ID *)ob, 'r', framenr, stack_index);
 +      if(!fp)
 +              ret = 0;
 +      else {
 +              for(a = 0; a < cloth->numverts; a++)
 +              {
 +                      if(fread(&cloth->x[a], sizeof(float), 4, fp) != 4) 
 +                      {
 +                              ret = 0;
 +                              break;
 +                      }
 +                      if(fread(&cloth->xconst[a], sizeof(float), 4, fp) != 4) 
 +                      {
 +                              ret = 0;
 +                              break;
 +                      }
 +                      if(fread(&cloth->v[a], sizeof(float), 4, fp) != 4) 
 +                      {
 +                              ret = 0;
 +                              break;
 +                      }
 +              }
 +              
 +              fclose(fp);
 +      }
 +      
 +      implicit_set_positions(clmd);
 +                      
 +      return ret;
 +}
 +
 +/************************************************
 + * clothModifier_do - main simulation function
 +************************************************/
 +DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
 +{
 +      unsigned int i;
 +      unsigned int numverts = -1;
 +      unsigned int numedges = -1;
 +      unsigned int numfaces = -1;
 +      MVert *mvert = NULL;
 +      MEdge *medge = NULL;
 +      MFace *mface = NULL;
 +      DerivedMesh *result = NULL;
 +      Cloth *cloth = clmd->clothObject;
 +      unsigned int framenr = (float)G.scene->r.cfra;
 +      float current_time = bsystem_time(ob, (float)G.scene->r.cfra, 0.0);
 +      ListBase *effectors = NULL;
 +      float deltaTime = current_time - clmd->sim_parms->sim_time;     
 +
 +      clmd->sim_parms->dt = 1.0f / (clmd->sim_parms->stepsPerFrame * G.scene->r.frs_sec);
 +
 +      result = CDDM_copy(dm);
 +      
 +      if(!result)
 +      {
 +              return dm;
 +      }
 +      
 +      numverts = result->getNumVerts(result);
 +      numedges = result->getNumEdges(result);
 +      numfaces = result->getNumFaces(result);
 +      mvert = CDDM_get_verts(result);
 +      medge = CDDM_get_edges(result);
 +      mface = CDDM_get_faces(result);
 +
 +      clmd->sim_parms->sim_time = current_time;
 +      
 +      if ( current_time < clmd->sim_parms->firstframe )
 +              return result;
 +      
 +      // only be active during a specific period:
 +      // that's "first frame" and "last frame" on GUI
 +      /*
 +      if ( clmd->clothObject )
 +      {
 +      if ( clmd->sim_parms->cache )
 +      {
 +      if ( current_time < clmd->sim_parms->firstframe )
 +      {
 +      int frametime = cloth_cache_first_frame ( clmd );
 +      if ( cloth_cache_search_frame ( clmd, frametime ) )
 +      {
 +      cloth_cache_get_frame ( clmd, frametime );
 +      cloth_to_object ( ob, result, clmd );
 +}
 +      return result;
 +}
 +      else if ( current_time > clmd->sim_parms->lastframe )
 +      {
 +      int frametime = cloth_cache_last_frame ( clmd );
 +      if ( cloth_cache_search_frame ( clmd, frametime ) )
 +      {
 +      cloth_cache_get_frame ( clmd, frametime );
 +      cloth_to_object ( ob, result, clmd );
 +}
 +      return result;
 +}
 +      else if ( ABS ( deltaTime ) >= 2.0f ) // no timewarps allowed
 +      {
 +      if ( cloth_cache_search_frame ( clmd, framenr ) )
 +      {
 +      cloth_cache_get_frame ( clmd, framenr );
 +      cloth_to_object ( ob, result, clmd );
 +}
 +      clmd->sim_parms->sim_time = current_time;
 +      return result;
 +}
 +}
 +}
 +      */
 +      
 +      if(deltaTime == 1.0f)
 +      {
 +              if ((clmd->clothObject == NULL) || (numverts != clmd->clothObject->numverts) ) 
 +              {
 +                      cloth_clear_cache(ob, clmd, 0);
 +                      
 +                      if(!cloth_from_object (ob, clmd, result, dm, framenr))
 +                              return result;
 +
 +                      if(clmd->clothObject == NULL)
 +                              return result;
 +
 +                      cloth = clmd->clothObject;
 +              }
 +
 +              clmd->clothObject->old_solver_type = clmd->sim_parms->solver_type;
 +
 +              // Insure we have a clmd->clothObject, in case allocation failed.
 +              if (clmd->clothObject != NULL) 
 +              {
 +                      if(!cloth_read_cache(ob, clmd, framenr))
 +                      {
 +                              // Force any pinned verts to their constrained location.
 +                              // has to be commented for verlet
 +                              for ( i = 0; i < clmd->clothObject->numverts; i++ )
 +                              {
 +                                      // Save the previous position.
 +                                      VECCOPY ( cloth->xold[i], cloth->xconst[i] );
 +                                      VECCOPY ( cloth->current_xold[i], cloth->x[i] );
 +                                      // Get the current position.
 +                                      VECCOPY ( cloth->xconst[i], mvert[i].co );
 +                                      Mat4MulVecfl ( ob->obmat, cloth->xconst[i] );
 +                              }
 +                              
 +                              tstart();
 +                              
 +                              /* Call the solver. */
 +                              if (solvers [clmd->sim_parms->solver_type].solver)
 +                                      solvers [clmd->sim_parms->solver_type].solver (ob, framenr, clmd, effectors);
 +                              
 +                              tend();
 +                              
 +                              printf("Cloth simulation time: %f\n", tval());
 +                              
 +                              cloth_write_cache(ob, clmd, framenr);
 +                      }
 +
 +                      // Copy the result back to the object.
 +                      cloth_to_object (ob, result, clmd);
 +                      
 +                      // bvh_free(clmd->clothObject->tree);
 +                      // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms->epsilon);
 +              } 
 +
 +      }
 +      else if ( ( deltaTime <= 0.0f ) || ( deltaTime > 1.0f ) )
 +      {
 +              if ( clmd->clothObject != NULL )
 +              {
 +                      if(cloth_read_cache(ob, clmd, framenr))
 +                              cloth_to_object (ob, result, clmd);
 +              }
 +      }
 +      
 +      return result;
 +}
 +
 +/* frees all */
 +void cloth_free_modifier (ClothModifierData *clmd)
 +{
 +      Cloth   *cloth = NULL;
 +
 +      if(!clmd)
 +              return;
 +
 +      cloth = clmd->clothObject;
 +
 +      // free our frame cache
 +      // cloth_clear_cache(ob, clmd, 0);
 +
 +      /* Calls the solver and collision frees first as they
 +      * might depend on data in clmd->clothObject. */
 +
 +      if (cloth) 
 +      {       
 +              // If our solver provides a free function, call it
 +              if (cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free) 
 +              {       
 +                      solvers [cloth->old_solver_type].free (clmd);
 +              }
 +              
 +              // Free the verts.
 +              if (cloth->verts != NULL)
 +                      MEM_freeN (cloth->verts);
 +              
 +              // Free the faces.
 +              if ( cloth->mfaces != NULL )
 +                      MEM_freeN ( cloth->mfaces );
 +              
 +              // Free the verts.
 +              if ( cloth->x != NULL )
 +                      MEM_freeN ( cloth->x );
 +              
 +              // Free the verts.
 +              if ( cloth->xold != NULL )
 +                      MEM_freeN ( cloth->xold );
 +              
 +              // Free the verts.
 +              if ( cloth->v != NULL )
 +                      MEM_freeN ( cloth->v );
 +              
 +              // Free the verts.
 +              if ( cloth->current_x != NULL )
 +                      MEM_freeN ( cloth->current_x );
 +              
 +              // Free the verts.
 +              if ( cloth->current_xold != NULL )
 +                      MEM_freeN ( cloth->current_xold );
 +              
 +              // Free the verts.
 +              if ( cloth->current_v != NULL )
 +                      MEM_freeN ( cloth->current_v );
 +              
 +              // Free the verts.
 +              if ( cloth->xconst != NULL )
 +                      MEM_freeN ( cloth->xconst );
 +              
 +              cloth->verts = NULL;
 +              cloth->numverts = -1;
 +              
 +              // Free the springs.
 +              if ( cloth->springs != NULL )
 +              {
 +                      LinkNode *search = cloth->springs;
 +                      while(search)
 +                      {
 +                              ClothSpring *spring = search->link;
 +                                              
 +                              MEM_freeN ( spring );
 +                              search = search->next;
 +                      }
 +                      BLI_linklist_free(cloth->springs, NULL);
 +              
 +                      cloth->springs = NULL;
 +              }
 +
 +              cloth->numsprings = -1;
 +              
 +              // free BVH collision tree
 +              if(cloth->tree)
 +                      bvh_free((BVH *)cloth->tree);
 +              
 +              // free BVH self collision tree
 +              if(cloth->selftree)
 +                      bvh_free((BVH *)cloth->selftree);
 +              
 +              if(cloth->edgehash)
 +                      BLI_edgehash_free ( cloth->edgehash, NULL );
 +              
 +              MEM_freeN (cloth);
 +              clmd->clothObject = NULL;
 +      }
 +
 +}
 +
 +
 +
 +/******************************************************************************
 +*
 +* Internal functions.
 +*
 +******************************************************************************/
 +
 +/**
 + * cloth_to_object - copies the deformed vertices to the object.
 + *
 + * This function is a modified version of the softbody.c:softbody_to_object() function.
 + **/
 +static void cloth_to_object (Object *ob,  DerivedMesh *dm, ClothModifierData *clmd)
 +{
 +      unsigned int    i = 0;
 +      MVert *mvert = NULL;
 +      unsigned int numverts;
 +      Cloth *cloth = clmd->clothObject;
 +
 +      if (clmd->clothObject) {
 +              /* inverse matrix is not uptodate... */
 +              Mat4Invert (ob->imat, ob->obmat);
 +
 +              mvert = CDDM_get_verts(dm);
 +              numverts = dm->getNumVerts(dm);
 +
 +              for (i = 0; i < numverts; i++)
 +              {
 +                      VECCOPY (mvert[i].co, cloth->x[i]);
 +                      Mat4MulVecfl (ob->imat, mvert[i].co);   /* cloth is in global coords */
 +              }
 +      }
 +}
 +
 +
 +/**
 + * cloth_apply_vgroup - applies a vertex group as specified by type
 + *
 + **/
 +static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup)
 +{
 +      unsigned int i = 0;
 +      unsigned int j = 0;
 +      MDeformVert     *dvert = NULL;
 +      Cloth *clothObj = NULL;
 +      unsigned int numverts = 0;
 +      float goalfac = 0;
 +      ClothVertex *verts = NULL;
 +
 +      clothObj = clmd->clothObject;
 +
 +      if ( !dm )
 +              return;
 +
 +      numverts = dm->getNumVerts(dm);
 +
 +      /* vgroup is 1 based, decrement so we can match the right group. */
 +      --vgroup;
 +
 +      verts = clothObj->verts;
 +
 +      for ( i = 0; i < numverts; i++, verts++ )
 +      {
 +              // LATER ON, support also mass painting here
 +              if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
 +              {
 +                      dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT );
 +                      if ( dvert )
 +                      {
 +                              for ( j = 0; j < dvert->totweight; j++ )
 +                              {
 +                                      if ( dvert->dw[j].def_nr == vgroup )
 +                                      {
 +                                              verts->goal = dvert->dw [j].weight;
 +
 +                                              goalfac= ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal );
 +                                              verts->goal  = ( float ) pow ( verts->goal , 4.0f );
 +
 +                                              if ( dvert->dw [j].weight >=SOFTGOALSNAP )
 +                                              {
 +                                                      verts->flags |= CVERT_FLAG_PINNED;
 +                                              }
 +
 +                                              // TODO enable mass painting here, for the moment i let "goals" go first
 +
 +                                              break;
 +                                      }
 +                              }
 +                      }
 +              }
 +      }
 +}
 +              
 +// only meshes supported at the moment
 +static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, DerivedMesh *olddm, float framenr)
 +{
 +      unsigned int i;
 +      unsigned int numverts = dm->getNumVerts(dm);
 +      MVert *mvert = CDDM_get_verts(dm);
 +      float tnull[3] = {0,0,0};
 +      
 +      /* If we have a clothObject, free it. */
 +      if (clmd->clothObject != NULL)
 +              cloth_free_modifier (clmd);
 +
 +      /* Allocate a new cloth object. */
 +      clmd->clothObject = MEM_callocN (sizeof(Cloth), "cloth");
 +      if (clmd->clothObject) 
 +      {
 +              clmd->clothObject->old_solver_type = 255;
 +              clmd->clothObject->edgehash = NULL;
 +      }
 +      else if (clmd->clothObject == NULL) 
 +      {
 +              modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject.");
 +              return 0;
 +      }
 +
 +      switch (ob->type)
 +      {
 +              case OB_MESH:
 +              
 +                      // mesh input objects need DerivedMesh
 +                      if ( !dm )
 +                              return 0;
 +
 +                      cloth_from_mesh (ob, clmd, dm, framenr);
 +
 +                      if ( clmd->clothObject != NULL )
 +                      {
 +                              /* create springs */
 +                              clmd->clothObject->springs = NULL;
 +                              clmd->clothObject->numsprings = -1;
 +                                      
 +                              /* set initial values */
 +                              for (i = 0; i < numverts; ++i)
 +                              {
 +                                      VECCOPY (clmd->clothObject->x[i], mvert[i].co);
 +                                      Mat4MulVecfl(ob->obmat, clmd->clothObject->x[i]);
 +      
 +                                      clmd->clothObject->verts [i].mass = clmd->sim_parms->mass;
 +                                      if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
 +                                              clmd->clothObject->verts [i].goal= clmd->sim_parms->defgoal;
 +                                      else
 +                                              clmd->clothObject->verts [i].goal= 0.0;
 +                                      clmd->clothObject->verts [i].flags = 0;
 +                                      VECCOPY(clmd->clothObject->xold[i], clmd->clothObject->x[i]);
 +                                      VECCOPY(clmd->clothObject->xconst[i], clmd->clothObject->x[i]);
 +                                      VECCOPY(clmd->clothObject->current_xold[i], clmd->clothObject->x[i]);
 +                                      VecMulf(clmd->clothObject->v[i], 0.0);
 +      
 +                                      clmd->clothObject->verts [i].impulse_count = 0;
 +                                      VECCOPY ( clmd->clothObject->verts [i].impulse, tnull );
 +                              }
 +                              
 +                              if (!cloth_build_springs (clmd->clothObject, dm) )
 +                              {
 +                                      modifier_setError (&(clmd->modifier), "Can't build springs.");
 +                                      return 0;
 +                              }  
 +      
 +                              /* apply / set vertex groups */
 +                              if (clmd->sim_parms->vgroup_mass > 0)
 +                                      cloth_apply_vgroup (clmd, olddm, clmd->sim_parms->vgroup_mass);
 +      
 +                              /* init our solver */
 +                              if (solvers [clmd->sim_parms->solver_type].init)
 +                                      solvers [clmd->sim_parms->solver_type].init (ob, clmd);
 +      
 +                              clmd->clothObject->tree = bvh_build_from_float3(CDDM_get_faces(dm), dm->getNumFaces(dm), clmd->clothObject->x, numverts, clmd->coll_parms->epsilon);
 +                              
 +                              clmd->clothObject->selftree = bvh_build_from_float3(NULL, 0, clmd->clothObject->x, numverts, clmd->coll_parms->selfepsilon);
 +                              
 +                              // save initial state
 +                              cloth_write_cache(ob, clmd, framenr-1);
 +                      }
 +                      return 1;
 +                      default: return 0; // TODO - we do not support changing meshes
 +      }
 +      
 +      return 0;
 +}
 +
 +static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr)
 +{
 +      unsigned int numverts = dm->getNumVerts(dm);
 +      unsigned int numfaces = dm->getNumFaces(dm);
 +      MFace *mface = CDDM_get_faces(dm);
 +
 +      /* Allocate our vertices.
 +      */
 +      clmd->clothObject->numverts = numverts;
 +      clmd->clothObject->verts = MEM_callocN (sizeof (ClothVertex) * clmd->clothObject->numverts, "clothVertex");
 +      if (clmd->clothObject->verts == NULL) 
 +      {
 +              cloth_free_modifier (clmd);
 +              modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts.");
 +              return;
 +      }
 +      
 +      clmd->clothObject->x = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_x" );
 +      if ( clmd->clothObject->x == NULL )
 +      {
 +              cloth_free_modifier ( clmd );
 +              modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->x." );
 +              return;
 +      }
 +      
 +      clmd->clothObject->xold = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_xold" );
 +      if ( clmd->clothObject->xold == NULL )
 +      {
 +              cloth_free_modifier ( clmd );
 +              modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->xold." );
 +              return;
 +      }
 +      
 +      clmd->clothObject->v = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_v" );
 +      if ( clmd->clothObject->v == NULL )
 +      {
 +              cloth_free_modifier ( clmd );
 +              modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->v." );
 +              return;
 +      }
 +      
 +      clmd->clothObject->current_x = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_current_x" );
 +      if ( clmd->clothObject->current_x == NULL )
 +      {
 +              cloth_free_modifier ( clmd );
 +              modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->current_x." );
 +              return;
 +      }
 +      
 +      clmd->clothObject->current_xold = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_current_xold" );
 +      if ( clmd->clothObject->current_xold == NULL )
 +      {
 +              cloth_free_modifier ( clmd );
 +              modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->current_xold." );
 +              return;
 +      }
 +      
 +      clmd->clothObject->current_v = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_current_v" );
 +      if ( clmd->clothObject->current_v == NULL )
 +      {
 +              cloth_free_modifier ( clmd );
 +              modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->current_v." );
 +              return;
 +      }
 +      
 +      clmd->clothObject->xconst = MEM_callocN ( sizeof ( float ) * clmd->clothObject->numverts * 4, "Cloth MVert_xconst" );
 +      if ( clmd->clothObject->xconst == NULL )
 +      {
 +              cloth_free_modifier ( clmd );
 +              modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->xconst." );
 +              return;
 +      }
 +
 +      // save face information
 +      clmd->clothObject->numfaces = numfaces;
 +      clmd->clothObject->mfaces = MEM_callocN (sizeof (MFace) * clmd->clothObject->numfaces, "clothMFaces");
 +      if (clmd->clothObject->mfaces == NULL) 
 +      {
 +              cloth_free_modifier (clmd);
 +              modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->mfaces.");
 +              return;
 +      }
 +      memcpy(clmd->clothObject->mfaces, mface, sizeof(MFace)*numfaces);
 +
 +      /* Free the springs since they can't be correct if the vertices
 +      * changed.
 +      */
 +      if (clmd->clothObject->springs != NULL)
 +              MEM_freeN (clmd->clothObject->springs);
 +
 +}
 +
 +/***************************************************************************************
 +* SPRING NETWORK BUILDING IMPLEMENTATION BEGIN
 +***************************************************************************************/
 +
 +// be carefull: implicit solver has to be resettet when using this one!
 +int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned int indexB, float restlength, int spring_type)
 +{
 +      Cloth *cloth = clmd->clothObject;
 +      ClothSpring *spring = NULL;
 +      
 +      if(cloth)
 +      {
 +              // TODO: look if this spring is already there
 +              
 +              spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
 +              
 +              spring->ij = indexA;
 +              spring->kl = indexB;
 +              spring->restlen =  restlength;
 +              spring->type = spring_type;
 +              spring->flags = 0;
 +              
 +              cloth->numsprings++;
 +      
 +              BLI_linklist_append ( &cloth->springs, spring );
 +              
 +              return 1;
 +      }
 +      return 0;
 +}
 +
 +int cloth_build_springs ( Cloth *cloth, DerivedMesh *dm )
 +{
 +      ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL;
 +      unsigned int struct_springs = 0, shear_springs=0, bend_springs = 0;
++      unsigned int i = 0, j = 0;
 +      unsigned int numverts = dm->getNumVerts ( dm );
 +      unsigned int numedges = dm->getNumEdges ( dm );
 +      unsigned int numfaces = dm->getNumFaces ( dm );
 +      MEdge *medge = CDDM_get_edges ( dm );
 +      MFace *mface = CDDM_get_faces ( dm );
 +      unsigned int index2 = 0; // our second vertex index
 +      LinkNode **edgelist = NULL;
 +      EdgeHash *edgehash = NULL;
 +      LinkNode *search = NULL, *search2 = NULL;
 +      float temp[3];
 +      LinkNode *node = NULL, *node2 = NULL;
 +      
 +      // error handling
 +      if ( numedges==0 )
 +              return 0;
 +
 +      cloth->springs = NULL;
 +
 +      edgelist = MEM_callocN ( sizeof ( LinkNode * ) * numverts, "cloth_edgelist_alloc" );
 +      for ( i = 0; i < numverts; i++ )
 +      {
 +              edgelist[i] = NULL;
 +      }
 +
 +      if ( cloth->springs )
 +              MEM_freeN ( cloth->springs );
 +
 +      // create spring network hash
 +      edgehash = BLI_edgehash_new();
 +
 +      // structural springs
 +      for ( i = 0; i < numedges; i++ )
 +      {
 +              spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
 +
 +              if ( spring )
 +              {
 +                      spring->ij = medge[i].v1;
 +                      spring->kl = medge[i].v2;
 +                      VECSUB ( temp, cloth->x[spring->kl], cloth->x[spring->ij] );
 +                      spring->restlen =  sqrt ( INPR ( temp, temp ) );
 +                      spring->type = CLOTH_SPRING_TYPE_STRUCTURAL;
 +                      spring->flags = 0;
 +                      struct_springs++;
 +                      
 +                      if(!i)
 +                              node2 = BLI_linklist_append_fast ( &cloth->springs, spring );
 +                      else
 +                              node2 = BLI_linklist_append_fast ( &node->next, spring );
 +                      node = node2;
 +              }
 +      }
 +      
++      // calc collision balls *slow*
++      // better: use precalculated list with O(1) index access to all springs of a vertex
++      // missing for structural since it's not needed for building bending springs
++      /*
++      for ( i = 0; i < numverts; i++ )
++      {
++              search = cloth->springs;
++              for ( j = 0; j < struct_springs; j++ )
++              {
++                      if ( !search )
++                              break;
++
++                      tspring = search->link;
++                      
++                      if((tspring->ij == i) || (tspring->kl == i))
++                      {
++                              akku += bs->len;
++                              akku_count++,
++                              min = MIN2(bs->len,min);
++                              max = MAX2(bs->len,max);
++                      }
++              }
++      }
++      */
 +      // shear springs
 +      for ( i = 0; i < numfaces; i++ )
 +      {
 +              spring = ( ClothSpring *) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
 +
 +              spring->ij = mface[i].v1;
 +              spring->kl = mface[i].v3;
 +              VECSUB ( temp, cloth->x[spring->kl], cloth->x[spring->ij] );
 +              spring->restlen =  sqrt ( INPR ( temp, temp ) );
 +              spring->type = CLOTH_SPRING_TYPE_SHEAR;
 +
 +              BLI_linklist_append ( &edgelist[spring->ij], spring );
 +              BLI_linklist_append ( &edgelist[spring->kl], spring );
 +              shear_springs++;
 +
 +              node2 = BLI_linklist_append_fast ( &node->next, spring );
 +              node = node2;
 +
 +              if ( mface[i].v4 )
 +              {
 +                      spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
 +
 +                      spring->ij = mface[i].v2;
 +                      spring->kl = mface[i].v4;
 +                      VECSUB ( temp, cloth->x[spring->kl], cloth->x[spring->ij] );
 +                      spring->restlen =  sqrt ( INPR ( temp, temp ) );
 +                      spring->type = CLOTH_SPRING_TYPE_SHEAR;
 +
 +                      BLI_linklist_append ( &edgelist[spring->ij], spring );
 +                      BLI_linklist_append ( &edgelist[spring->kl], spring );
 +                      shear_springs++;
 +
 +                      node2 = BLI_linklist_append_fast ( &node->next, spring );
 +                      node = node2;
 +              }
 +      }
 +      
 +      // bending springs
 +      search2 = cloth->springs;
 +      for ( i = struct_springs; i < struct_springs+shear_springs; i++ )
 +      {
 +              if ( !search2 )
 +                      break;
 +
 +              tspring2 = search2->link;
 +              search = edgelist[tspring2->kl];
 +              while ( search )
 +              {
 +                      tspring = search->link;
 +                      index2 = ( ( tspring->ij==tspring2->kl ) ? ( tspring->kl ) : ( tspring->ij ) );
 +                      
 +                      // check for existing spring
 +                      // check also if startpoint is equal to endpoint
 +                      if ( !BLI_edgehash_haskey ( edgehash, index2, tspring2->ij )
 +                      && !BLI_edgehash_haskey ( edgehash, tspring2->ij, index2 )
 +                      && ( index2!=tspring2->ij ) )
 +                      {
 +                              spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
 +
 +                              spring->ij = tspring2->ij;
 +                              spring->kl = index2;
 +                              VECSUB ( temp, cloth->x[index2], cloth->x[tspring2->ij] );
 +                              spring->restlen =  sqrt ( INPR ( temp, temp ) );
 +                              spring->type = CLOTH_SPRING_TYPE_BENDING;
 +                              BLI_edgehash_insert ( edgehash, spring->ij, index2, NULL );
 +                              bend_springs++;
 +
 +                              node2 = BLI_linklist_append_fast ( &node->next, spring );
 +                              node = node2;
 +                      }
 +                      search = search->next;
 +              }
 +              search2 = search2->next;
 +      }
 +      
 +      cloth->numspringssave = cloth->numsprings = struct_springs + shear_springs + bend_springs;
 +      cloth->numothersprings = struct_springs + shear_springs;
 +      
 +      for ( i = 0; i < numverts; i++ )
 +      {
 +              BLI_linklist_free ( edgelist[i],NULL );
 +      }
 +      if ( edgelist )
 +              MEM_freeN ( edgelist );
 +      
 +      cloth->edgehash = edgehash;
 +
 +      return 1;
 +
 +} /* cloth_build_springs */
 +/***************************************************************************************
 +* SPRING NETWORK BUILDING IMPLEMENTATION END
 +***************************************************************************************/
 +
index 85dc1ca44fbf7f1af456bd2c31e09260cdb60696,9336dde01510fb256397c7725ee09486f24ca238..998a15df28cbe8348227ae8d9e0bd10acb3e44f2
  #include "BKE_main.h"
  #include "BKE_anim.h"
  #include "BKE_bad_level_calls.h"
 +#include "BKE_collisions.h"
+ #include "BKE_curve.h"
  #include "BKE_customdata.h"
  #include "BKE_global.h"
- #include "BKE_utildefines.h"
  #include "BKE_cdderivedmesh.h"
  #include "BKE_DerivedMesh.h"
  #include "BKE_booleanops.h"
  #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"
+ #include "BKE_utildefines.h"
  #include "depsgraph_private.h"
  
  #include "LOD_DependKludge.h"
@@@ -6093,13 -6983,13 +7262,20 @@@ int modifiers_isSoftbodyEnabled(Object 
        return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
  }
  
 +ClothModifierData *modifiers_isClothEnabled(Object *ob)
 +{
 +      ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
 +
 +      return clmd;
 +}
 +
+ int modifiers_isParticleEnabled(Object *ob)
+ {
+       ModifierData *md = modifiers_findByType(ob, eModifierType_ParticleSystem);
+       return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
+ }
  LinkNode *modifiers_calcDataMasks(ModifierData *md, CustomDataMask dataMask)
  {
        LinkNode *dataMasks = NULL;
index 6d16a326a0ba5c8a0751a9ef8a6ce5e82c7282d6,65608507d0ef12c713fa757a9d67886e1dd46573..35562a11db5b6e0ac14ef3bfdbc0278854872679
@@@ -3036,7 -3105,9 +3128,8 @@@ static void direct_link_object(FileDat
                sb->bpoint= NULL;       // init pointers so it gets rebuilt nicely
                sb->bspring= NULL;
                sb->scratch= NULL;
-               
 -
+               /* although not used anymore */
+               /* still have to be loaded to be compatible with old files */
                sb->keys= newdataadr(fd, sb->keys);
                test_pointer_array(fd, (void **)&sb->keys);
                if(sb->keys) {
index 6f440ed7cbc30094a4153e3b27d97c5c1beb9e8e,10a31de98e563a9c51a78fc1fe9d28c9f7d084a9..3666067ee2ce129bf379695586288e7ecf1b3966
@@@ -282,14 -286,8 +286,15 @@@ void curvemap_buttons(struct uiBlock *b
  #define B_GROUP_RELINK                        1460
  #define B_OBJECT_IPOFLAG              1461
  
+ #define B_BAKEABLE_CHANGE             1470
  
- #define B_CLOTH_CLEARCACHEALL         1470
- #define B_CLOTH_CLEARCACHEFRAME               1471
- #define B_CLOTH_CHANGEPREROLL                 1472
- #define B_CLOTH_DEL_VG                                        1473
- #define B_CLOTH_RENEW         1474
 +/* Cloth sim button defines */
++#define B_CLOTH_CLEARCACHEALL 1480
++#define B_CLOTH_CLEARCACHEFRAME       1481
++#define B_CLOTH_CHANGEPREROLL 1482
++#define B_CLOTH_DEL_VG                1483
++#define B_CLOTH_RENEW                 1484
 +
  /* *********************** */
  #define B_WORLDBUTS           1600
  
index 903f1a540b3a07b1e7f255550c1f4437e954f6b8,982df45e77a8aa6df1c9ae9828bb0a74611a284b..65eec871404030d5af4875476b91701e4e84705a
@@@ -29,9 -29,9 +29,11 @@@ typedef enum ModifierType 
        eModifierType_Smooth,
        eModifierType_Cast,
        eModifierType_MeshDeform,
-       eModifierType_PointCache,
+       eModifierType_ParticleSystem,
+       eModifierType_ParticleInstance,
+       eModifierType_Explode,
 +      eModifierType_Cloth,
-         eModifierType_Collision,      
++        eModifierType_Collision,
        NUM_MODIFIER_TYPES
  } ModifierType;
  
index 41a8e8127f0d3ecc6cac5457ca9b67097e9cd5bd,f696c45b3154904c6930b6875c28a90d6ac9056f..ecf2a8e73b0dc483e6cc18ac28aee96878e80940
@@@ -127,7 -127,7 +127,8 @@@ char *includefiles[] = 
        "DNA_color_types.h",
        "DNA_brush_types.h",
        "DNA_customdata_types.h",
+       "DNA_particle_types.h",
 +      "DNA_cloth_types.h",
        // if you add files here, please add them at the end
        // of makesdna.c (this file) as well
  
@@@ -1147,5 -1147,5 +1148,6 @@@ int main(int argc, char ** argv
  #include "DNA_color_types.h"
  #include "DNA_brush_types.h"
  #include "DNA_customdata_types.h"
+ #include "DNA_particle_types.h"
 +#include "DNA_cloth_types.h"
  /* end of list */
index 70d1c0920662f521324acc1b5483d6898d30ae81,bebd3e1962ffa1a278cf51627f1418450ab603d6..6ae2cd73df3fca177f2df260e84873f8c2f6ca54
@@@ -951,9 -954,7 +954,9 @@@ static uiBlock *modifiers_add_menu(voi
                ModifierTypeInfo *mti = modifierType_getInfo(i);
  
                /* Only allow adding through appropriate other interfaces */
-               if(ELEM(i, eModifierType_Softbody, eModifierType_Hook)) continue;
+               if(ELEM3(i, eModifierType_Softbody, eModifierType_Hook, eModifierType_ParticleSystem)) continue;
 +              
 +              if(ELEM(i, eModifierType_Cloth, eModifierType_Collision)) continue;
  
                if((mti->flags&eModifierTypeFlag_AcceptsCVs) ||
                   (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
@@@ -1656,11 -1744,7 +1758,11 @@@ static void draw_modifier(uiBlock *bloc
                        if(hmd->indexar==NULL)
                                height += 20;
                } else if (md->type==eModifierType_Softbody) {
-                       height = 26;
+                       height = 31;
 +              } else if (md->type==eModifierType_Cloth) {
 +                      height = 26;
 +              } else if (md->type==eModifierType_Collision) {
 +                      height = 19;
                } else if (md->type==eModifierType_Boolean) {
                        height = 48;
                } else if (md->type==eModifierType_Array) {
                } else if (md->type==eModifierType_MeshDeform) {
                        MeshDeformModifierData *mmd= (MeshDeformModifierData*)md;
                        height = (mmd->bindcos)? 73: 93;
-               } else if (md->type==eModifierType_PointCache) {
-                       height = 48;
-               } 
-               
+               } else if (md->type==eModifierType_ParticleSystem) {
+                       height = 31;
+               } else if (md->type==eModifierType_ParticleInstance) {
+                       height = 94;
+               } else if (md->type==eModifierType_Explode) {
+                       height = 94;
+               }
 -
                                                        /* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
                uiDefBut(block, ROUNDBOX, 0, "", x-10, y-height-2, width, height-2, NULL, 5.0, 0.0, 12, 40, ""); 
  
                y -= 18;
  
 -              if (!isVirtual) {
 +              if (!isVirtual && (md->type!=eModifierType_Collision)) {
                        uiBlockBeginAlign(block);
-                       but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Apply",  lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Apply the current modifier and remove from the stack");
-                       uiButSetFunc(but, modifiers_applyModifier, ob, md);
-                       if ((md->type!=eModifierType_Softbody) && (md->type!=eModifierType_Cloth)) {
+                       if (md->type==eModifierType_ParticleSystem) {
+                               but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Convert",        lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Convert the current particles to a mesh object");
+                               uiButSetFunc(but, modifiers_convertParticles, ob, md);
+                       }
+                       else{
+                               but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Apply",  lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Apply the current modifier and remove from the stack");
+                               uiButSetFunc(but, modifiers_applyModifier, ob, md);
+                       }
+                       
 -                      if (md->type!=eModifierType_Softbody && md->type!=eModifierType_ParticleSystem) {
++                      if (md->type!=eModifierType_Softbody && md->type!=eModifierType_ParticleSystem && (md->type!=eModifierType_Cloth)) {
                                but = uiDefBut(block, BUT, B_MODIFIER_RECALC, "Copy",   lx,(cy-=19),60,19, 0, 0, 0, 0, 0, "Duplicate the current modifier at the same position in the stack");
                                uiButSetFunc(but, modifiers_copyModifier, ob, md);
                        }
index 838ee814d7eef404f5a21fe569180f20f42d328e,455b41d3f0ec5d50687a254fbef041cf15e3172d..a5be0e0357f080ce5459730977eda8b2698d67cd
@@@ -47,6 -47,6 +47,7 @@@
  #include "DNA_scene_types.h"
  
  #include "BKE_action.h"
++#include "BKE_cloth.h"
  #include "BKE_global.h"
  #include "BKE_main.h"
  #include "BKE_library.h"
@@@ -3854,6 -4618,6 +4620,233 @@@ errMessage
  #endif // DISABLE_ELBEEM
  }
  
++/* Panel for cloth */
++static void object_cloth__enabletoggle(void *ob_v, void *arg2)
++{
++      Object *ob = ob_v;
++      ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth);
++
++      if (!md) {
++              md = modifier_new(eModifierType_Cloth);
++              BLI_addhead(&ob->modifiers, md);
++      }
++      else {
++              BLI_remlink(&ob->modifiers, md);
++              modifier_free(md);
++      }
++
++      allqueue(REDRAWBUTSEDIT, 0);
++}
++
++static void object_panel_cloth(Object *ob)
++{
++      uiBlock *block;
++      static int val, val2;
++      uiBut *but;
++      ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
++      block= uiNewBlock(&curarea->uiblocks, "object_panel_cloth", UI_EMBOSS, UI_HELV, curarea->win);
++      if(uiNewPanel(curarea, block, "Cloth", "Physics", 640, 0, 318, 204)==0) return;
++
++      if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
++      val = ((clmd)?(1):(0));
++
++      but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Cloth Object",   10,200,130,20, &val, 0, 0, 0, 0, "Sets object to become cloth");
++      uiButSetFunc(but, object_cloth__enabletoggle, ob, NULL);
++      uiDefBut(block, LABEL, 0, "",10,10,300,0, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
++      
++      if(clmd)
++      {
++              // but = uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_COLLOBJ, B_EFFECT_DEP, "Collision Object",     170,200,130,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Sets object to become a cloth collision object");
++
++              if (!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ))
++              {
++                      Cloth *cloth = clmd->clothObject;
++                      int defCount;
++                      char *clvg1, *clvg2;
++                      char clmvg [] = "Mass Vertex Group%t|None%x0|";
++      
++                      val2=0;
++      
++      //              uiDefButBitI(block, TOG, CSIMSETT_FLAG_ADVANCED, REDRAWBUTSOBJECT, "Advanced",  180,200,130,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Enable advanced mode");
++                      
++                      /* GENERAL STUFF */
++                      uiClearButLock();
++                      uiBlockBeginAlign(block);
++                      uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:",       10,170,150,20, &clmd->sim_parms->structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure");
++                      uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:",         160,170,150,20, &clmd->sim_parms->bending, 0.0, 10000.0, 1000, 0, "Wrinkle possibility");
++                      uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:",  10,150,150,20, &clmd->sim_parms->stepsPerFrame, 3.0, 10.0, 5, 0, "Quality of the simulation (higher=>better=>slower)");
++                      uiBlockEndAlign(block);
++                      uiBlockBeginAlign(block);
++                      uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:",       160,150,150,20, &clmd->sim_parms->Cdis, 0.0, 10.0, 10, 0, "Spring damping");
++                      uiDefButF(block, NUM, B_DIFF, "Air Damp:",         10,130,150,20, &clmd->sim_parms->Cvi, 0.0, 10.0, 10, 0, "Apply gravitation to point movement");
++                      uiBlockEndAlign(block);                 
++                      
++                      uiClearButLock();
++                      
++                      uiBlockBeginAlign(block);
++                      uiDefBut(block, LABEL, 0, "Gravity:",  10,100,60,20, NULL, 0.0, 0, 0, 0, "");
++                      // uiClearButLock();
++                      
++                      uiDefButF(block, NUM, B_CLOTH_RENEW, "X:",         70,100,80,20, &clmd->sim_parms->gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
++                      uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:",         150,100,80,20, &clmd->sim_parms->gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
++                      uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:",         230,100,80,20, &clmd->sim_parms->gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
++                      uiBlockEndAlign(block);
++                      
++                      /* GOAL STUFF */
++                      uiBlockBeginAlign(block);
++                      uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, REDRAWVIEW3D, "Use Goal", 10,70,130,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
++                      if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
++                      {
++                              if(ob->type==OB_MESH) 
++                              {
++                                      
++                                      defCount = sizeof (clmvg);
++                                      clvg1 = get_vertexgroup_menustr (ob);
++                                      clvg2 = MEM_callocN (strlen (clvg1) + 1 + defCount, "clothVgMS");
++                                      if (! clvg2) {
++                                              printf ("draw_modifier: error allocating memory for cloth vertex group menu string.\n");
++                                              return;
++                                      }
++                                      defCount = BLI_countlist (&ob->defbase);
++                                      if (defCount == 0) 
++                                      {
++                                              clmd->sim_parms->vgroup_mass = 0;
++                                      }
++                                      sprintf (clvg2, "%s%s", clmvg, clvg1);
++                                      
++                                      uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2,    140,70,20,20, &clmd->sim_parms->vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups");     
++                                      MEM_freeN (clvg1);
++                                      MEM_freeN (clvg2);
++                                      
++                                      if(clmd->sim_parms->vgroup_mass) 
++                                      {
++                                              bDeformGroup *defGroup = BLI_findlink(&ob->defbase, clmd->sim_parms->vgroup_mass-1);
++                                              if(defGroup)
++                                                      uiDefBut(block, BUT, B_DIFF, defGroup->name,    160,70,130,20, NULL, 0.0, 0.0, 0, 0, "Name of current vertex group");
++                                              else
++                                                      uiDefBut(block, BUT, B_DIFF, "(no group)",      160,70,130,20, NULL, 0.0, 0.0, 0, 0, "Vertex Group doesn't exist anymore");
++                                              
++                                              uiDefIconBut(block, BUT, B_CLOTH_DEL_VG, ICON_X, 290,70,20,20, 0, 0, 0, 0, 0, "Disable use of vertex group");
++                                              
++                                      }
++                                      else
++                                              uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:",   160,70,150,20, &clmd->sim_parms->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used");
++                              
++                              }
++                              else 
++                              {
++                                      uiDefButS(block, TOG, B_CLOTH_RENEW, "W",                       140,70,20,20, &clmd->sim_parms->vgroup_mass, 0, 1, 0, 0, "Use control point weight values");
++                                      uiDefButF(block, NUM, B_CLOTH_RENEW, "Goal:",   160,70,150,20, &clmd->sim_parms->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used");
++                              }
++                              
++                              uiDefButF(block, NUM, B_CLOTH_RENEW, "G Stiff:",        10,50,150,20, &clmd->sim_parms->goalspring, 0.0, 500.0, 10, 0, "Goal (vertex target position) spring stiffness");
++                              uiDefButF(block, NUM, B_CLOTH_RENEW, "G Damp:", 160,50,150,20, &clmd->sim_parms->goalfrict, 0.0, 50.0, 10, 0, "Goal (vertex target position) friction");
++                              uiDefButF(block, NUM, B_CLOTH_RENEW, "G Min:",          10,30,150,20, &clmd->sim_parms->mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range");
++                              uiDefButF(block, NUM, B_CLOTH_RENEW, "G Max:",          160,30,150,20, &clmd->sim_parms->maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range");
++                      }
++                      uiBlockEndAlign(block); 
++                      
++                      /*
++                      // no tearing supported anymore since modifier stack restrictions 
++                      uiBlockBeginAlign(block);
++                      uiDefButBitI(block, TOG, CSIMSETT_FLAG_TEARING_ENABLED, B_EFFECT_DEP, "Tearing",        10,0,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Sets object to become a cloth collision object");
++                      
++                      if (clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED)
++                      {
++                              uiDefButI(block, NUM, B_DIFF, "Max extent:",       160,0,150,20, &clmd->sim_parms->maxspringlen, 1.0, 1000.0, 10, 0, "Maximum extension before spring gets cut");
++                      }
++                      
++                      uiBlockEndAlign(block); 
++                      */
++              }
++      }
++}
++
++
++static void object_panel_cloth_II(Object *ob)
++{
++      uiBlock *block;
++      static int val;
++      uiBut *but;
++      ClothModifierData *clmd = NULL;
++      
++      clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
++      if(clmd)
++      {
++              if (!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ))
++              {
++                      Cloth *cloth = clmd->clothObject;
++                      char str[128];
++                      
++                      block= uiNewBlock(&curarea->uiblocks, "object_panel_cloth_II", UI_EMBOSS, UI_HELV, curarea->win);
++                      uiNewPanelTabbed("Cloth", "Physics");
++                      if(uiNewPanel(curarea, block, "Cloth Cache", "Physics", 651, 0, 318, 204)==0) return;
++              
++                      uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
++                      
++                      uiDefButI(block, NUM, B_DIFF, "First Frame:",           10,160,150,20, &clmd->sim_parms->firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts");
++                      uiDefButI(block, NUM, B_DIFF, "Last Frame:",            160,160,150,20, &clmd->sim_parms->lastframe, 0, MAXFRAME, 10, 0, "Frame on which the simulation stops");
++                      /*
++                      if(clmd->sim_parms->cache)
++                      {
++                              int length = BLI_linklist_length(clmd->sim_parms->cache);
++                              
++                              // correct spelling if only 1 frame cacheed --> only gimmick  
++                              if(length-clmd->sim_parms->preroll>1)
++                                      sprintf (str, "Frame 1 - %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms->preroll, clmd->sim_parms->preroll, length);
++                              else
++                                      sprintf (str, "Frame %d cached. [%d in preroll, %d in total]", length-clmd->sim_parms->preroll, clmd->sim_parms->preroll, length);
++                              
++                              uiDefBut(block, LABEL, 0, str,  10,140,290,20, NULL, 0.0, 0, 0, 0, "");
++                              uiDefBut(block, LABEL, 0, "Clear cache:",  10,120,290,20, NULL, 0.0, 0, 0, 0, "");
++                              uiBlockBeginAlign (block);
++                              uiDefBut(block, BUT, B_CLOTH_CLEARCACHEALL, "All", 10, 100,145,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache without preroll");
++                              uiDefBut(block, BUT, B_CLOTH_CLEARCACHEFRAME, "From next frame", 155, 100,145,20, NULL, 0.0, 0.0, 0, 0, "Free cloth cache");    
++                              if(length>1) // B_CLOTH_CHANGEPREROLL
++                                      uiDefButI(block, NUM, B_CLOTH_CHANGEPREROLL, "Preroll:", 10,80,145,20, &clmd->sim_parms->preroll, 0, length-1, 1, 0, "Simulation starts on this frame");        
++                              else
++                                      uiDefBut(block, LABEL, 0, " ",  10,80,145,20, NULL, 0.0, 0, 0, 0, "");
++                      }
++                      else 
++                      {
++                              uiDefBut(block, LABEL, 0, "No frames cached.",  10,120,290,20, NULL, 0.0, 0, 0, 0, "");
++                      }*/
++                      uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache",  10,50,145,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed");
++                      uiBlockEndAlign(block);
++              }
++      }
++      // uiBlockEndAlign(block);
++}
++
++static void object_panel_cloth_III(Object *ob)
++{
++      uiBlock *block;
++      ClothModifierData *clmd = NULL;
++      
++      clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
++      if(clmd)
++      {       
++              block= uiNewBlock(&curarea->uiblocks, "object_panel_cloth_III", UI_EMBOSS, UI_HELV, curarea->win);
++              uiNewPanelTabbed("Cloth", "Physics");
++              if(uiNewPanel(curarea, block, "Cloth Collisions", "Physics", 651, 0, 318, 204)==0) return;
++      
++              uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
++              
++              uiBlockBeginAlign(block);
++              uiDefButBitI(block, TOG, CLOTH_COLLISIONSETTINGS_FLAG_ENABLED, REDRAWVIEW3D, "Enable collisions",       10,160,130,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable collisions with this object");
++              if (clmd->coll_parms->flags & CLOTH_COLLISIONSETTINGS_FLAG_ENABLED)
++              {
++                      // uiDefBut(block, LABEL, 0, "",10,10,300,20, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
++                      uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:",      10,140,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in");
++                      uiDefBut(block, LABEL, 0, "",160,140,150,20, NULL, 0.0, 0, 0, 0, "");
++                      uiDefButF(block, NUM, B_CLOTH_RENEW, "Selfcoll balls:",    10,120,150,20, &clmd->coll_parms->selfepsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between two selfcollision points");
++              }
++              else
++                      uiDefBut(block, LABEL, 0, "",140,10,170,20, NULL, 0.0, 0, 0, 0, "");
++              uiBlockEndAlign(block);
++      }
++}
++
  void object_panels()
  {
        Object *ob;
@@@ -3877,14 -4641,11 +4870,14 @@@ void physics_panels(
        /* check context here */
        ob= OBACT;
        if(ob) {
+               if(ob->type==OB_MESH)
+                       object_panel_deflection(ob);
                object_panel_fields(ob);
-               object_panel_particles(ob);
-               object_panel_particles_motion(ob);
                object_softbodies(ob);
                object_softbodies_II(ob);
 +              object_panel_cloth(ob);
 +              object_panel_cloth_II(ob);
 +              object_panel_cloth_III(ob);
                object_panel_fluidsim(ob);
        }
  }
Simple merge
index d357ad1bce58224337e2db7bd4a178c15af0b158,78284e11e744f65dec13d59da86dcc5d7b04d9d7..d43ff88597548ba442399e60ecac1535d946b852
@@@ -3049,11 -3214,13 +3215,14 @@@ void special_aftertrans_update(TransInf
                        allqueue(REDRAWBUTSEDIT, 0);
                
        }
+       else if(G.f & G_PARTICLEEDIT) {
+               ;
+       }
        else {
                base= FIRSTBASE;
 -              while (base) {  
 -                      
 +
 +              while (base) {                  
 +
                        if(base->flag & BA_DO_IPO) redrawipo= 1;
                        
                        ob= base->object;