svn merge -r 13382:13415 https://svn.blender.org/svnroot/bf-blender/trunk/blender
authorDaniel Genrich <daniel.genrich@gmx.net>
Sat, 26 Jan 2008 21:54:09 +0000 (21:54 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Sat, 26 Jan 2008 21:54:09 +0000 (21:54 +0000)
1  2 
source/blender/blenloader/intern/readfile.c
source/blender/include/butspace.h
source/blender/src/buttons_object.c
source/blender/src/editobject.c

index c725b3d63ac9ab714bfcf7e1a0ecb8238ee8c496,f3a3a3478acb97e007a63f869a6745a3452ee259..a9d2e7d05a1c1fb633d4f3acb6356726140ac7a4
@@@ -60,7 -60,6 +60,7 @@@
  #include "DNA_actuator_types.h"
  #include "DNA_brush_types.h"
  #include "DNA_camera_types.h"
 +#include "DNA_cloth_types.h"
  #include "DNA_color_types.h"
  #include "DNA_controller_types.h"
  #include "DNA_constraint_types.h"
  
  #include "BKE_action.h"
  #include "BKE_armature.h"
 +#include "BKE_cloth.h"
  #include "BKE_colortools.h"
  #include "BKE_constraint.h"
  #include "BKE_curve.h"
@@@ -1754,6 -1752,13 +1754,13 @@@ static void lib_link_constraints(FileDa
                                data->tar = newlibadr(fd, id->lib, data->tar);
                        }
                        break;
+               case CONSTRAINT_TYPE_DISTLIMIT:
+                       {
+                               bDistLimitConstraint *data;
+                               data= ((bDistLimitConstraint*)con->data);
+                               data->tar = newlibadr(fd, id->lib, data->tar);
+                       }
+                       break;
                case CONSTRAINT_TYPE_NULL:
                        break;
                }
@@@ -1767,6 -1772,7 +1774,7 @@@ static void direct_link_constraints(Fil
        link_list(fd, lb);
        for (cons=lb->first; cons; cons=cons->next) {
                cons->data = newdataadr(fd, cons->data);
+               
                if (cons->type == CONSTRAINT_TYPE_PYTHON) {
                        bPythonConstraint *data= cons->data;
                        link_list(fd, &data->targets);
@@@ -2998,43 -3004,7 +3006,43 @@@ static void direct_link_modifiers(FileD
                        SubsurfModifierData *smd = (SubsurfModifierData*) md;
  
                        smd->emCache = smd->mCache = 0;
 -              } else if (md->type==eModifierType_Hook) {
 +              }
 +              else if (md->type==eModifierType_Cloth) {
 +                      ClothModifierData *clmd = (ClothModifierData*) md;
 +                      
 +                      clmd->clothObject = NULL;
 +                      
 +                      clmd->sim_parms= newdataadr(fd, clmd->sim_parms);
 +                      clmd->coll_parms= newdataadr(fd, clmd->coll_parms);
 +                      
 +              }
 +              else if (md->type==eModifierType_Collision) {
 +                      
 +                      CollisionModifierData *collmd = (CollisionModifierData*) md;
 +                      /*
 +                      // TODO: CollisionModifier should use pointcache 
 +                      // + have proper reset events before enabling this
 +                      collmd->x = newdataadr(fd, collmd->x);
 +                      collmd->xnew = newdataadr(fd, collmd->xnew);
 +                      collmd->mfaces = newdataadr(fd, collmd->mfaces);
 +                      
 +                      collmd->current_x = MEM_callocN(sizeof(MVert)*collmd->numverts,"current_x");
 +                      collmd->current_xnew = MEM_callocN(sizeof(MVert)*collmd->numverts,"current_xnew");
 +                      collmd->current_v = MEM_callocN(sizeof(MVert)*collmd->numverts,"current_v");
 +                      */
 +                      
 +                      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;
 +                      
 +              }
 +              else if (md->type==eModifierType_Hook) {
                        HookModifierData *hmd = (HookModifierData*) md;
  
                        hmd->indexar= newdataadr(fd, hmd->indexar);
@@@ -3179,6 -3149,7 +3187,6 @@@ 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);
@@@ -7844,6 -7815,12 +7852,12 @@@ static void expand_constraints(FileDat
                                expand_doit(fd, mainvar, data->tar);
                        }
                        break;
+               case CONSTRAINT_TYPE_DISTLIMIT: 
+                       {
+                               bDistLimitConstraint *data = (bDistLimitConstraint*)curcon->data;
+                               expand_doit(fd, mainvar, data->tar);
+                       }
+                       break;
                default:
                        break;
                }
index a7759f799ba4e7f84849c4fdc95580a0bc0d3874,a067b3e1489d61e3f501b4ef01995e057c7e1811..28a58f7f9e4e40ac32bffaef615370b103278acf
@@@ -291,12 -291,6 +291,12 @@@ void curvemap_buttons(struct uiBlock *b
  
  #define B_BAKEABLE_CHANGE             1470
  
 +/* Cloth sim button defines */
 +#define B_CLOTH_CLEARCACHEALL 1480
 +#define B_CLOTH_CLEARCACHEFRAME       1481
 +#define B_CLOTH_CHANGEPREROLL 1482
 +#define B_CLOTH_RENEW                 1483
 +
  /* *********************** */
  #define B_WORLDBUTS           1600
  
@@@ -700,7 -694,7 +700,7 @@@ enum 
        B_CONSTRAINT_ADD_ACTION,
        B_CONSTRAINT_ADD_LOCKTRACK,
        B_CONSTRAINT_ADD_FOLLOWPATH,
-       B_CONSTRAINT_ADD_DISTANCELIMIT,
+       B_CONSTRAINT_ADD_DISTLIMIT,
        B_CONSTRAINT_ADD_STRETCHTO,
        B_CONSTRAINT_ADD_LOCLIMIT,
        B_CONSTRAINT_ADD_ROTLIMIT,
index 7b87dd2108c06c196eff6d28cde462260b217ac6,bbac5af9f3fa61b57b1ade8627567333c5a0b515..eb81c2562895a42c9322f78f9a68ec6fa0ffca9e
@@@ -47,7 -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"
@@@ -90,7 -89,6 +90,7 @@@
  #include "DNA_action_types.h"
  #include "DNA_armature_types.h"
  #include "DNA_camera_types.h"
 +#include "DNA_cloth_types.h"
  #include "DNA_constraint_types.h"
  #include "DNA_curve_types.h"
  #include "DNA_effect_types.h"
@@@ -604,13 -602,8 +604,8 @@@ static void draw_constraint (uiBlock *b
                uiBlockBeginAlign(block);
                        uiBlockSetEmboss(block, UI_EMBOSS);
                        
-                       if ((prev_proxylock) || (con->prev==NULL)) {
-                               /* don't draw 'button' behind arrow if disabled (and button doesn't do anything anyways) */
-                               uiBlockSetEmboss(block, UI_EMBOSSN);
-                               uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_UP, *xco+width-50, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint up in constraint stack");
-                               uiBlockSetEmboss(block, UI_EMBOSS);
-                       }
-                       else {
+                       /* only show buttons that will do anything valid */
+                       if ((prev_proxylock==0) && (con->prev)) {
                                but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_UP, *xco+width-50, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint up in constraint stack");
                                uiButSetFunc(but, constraint_moveUp, ob, con);
                        }
                                but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_DOWN, *xco+width-50+18, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint down in constraint stack");
                                uiButSetFunc(but, constraint_moveDown, ob, con);
                        }
-                       else {
-                               /* don't draw 'button' behind arrow if no next constraint (it doesn't do anything anyways) */
-                               uiBlockSetEmboss(block, UI_EMBOSSN);
-                               uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_DOWN, *xco+width-50+18, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint down in constraint stack");
-                               uiBlockSetEmboss(block, UI_EMBOSS);
-                       }
                uiBlockEndAlign(block);
                
                
                                draw_constraint_spaceselect(block, con, *xco, *yco-130, is_armature_owner(ob), -1);
                        }
                        break;
+               case CONSTRAINT_TYPE_DISTLIMIT:
+                       {
+                               bDistLimitConstraint *data = con->data;
+                               
+                               height = 105;
+                               uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
+                               
+                               uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
+                               
+                               /* Draw target parameters */
+                               uiBlockBeginAlign(block);
+                                       uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
+                                       
+                                       if (is_armature_target(data->tar)) {
+                                               but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
+                                               uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
+                                       }
+                                       else if (is_geom_target(data->tar)) {
+                                               but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
+                                               uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
+                                       }
+                                       else {
+                                               strcpy(data->subtarget, "");
+                                       }
+                               uiBlockEndAlign(block);
+                               
+                               uiBlockBeginAlign(block);
+                                       if (is_armature_target(data->tar)) {
+                                               uiDefButF(block, BUT, B_CONSTRAINT_TEST, "R", *xco, *yco-60, 20, 18, &data->dist, 0, 0, 0, 0, "Recalculate distance"); 
+                                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Distance:", *xco+18, *yco-60,139,18, &data->dist, 0.0, 100, 0.5, 0.5, "Radius of limiting sphere");
+                                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Head/Tail:", *xco+155, *yco-60,100,18, &con->headtail, 0.0, 1, 0.1, 0.1, "Target along length of bone: Head=0, Tail=1");
+                                       }
+                                       else {
+                                               uiDefButF(block, BUT, B_CONSTRAINT_TEST, "R", *xco, *yco-60, 20, 18, &data->dist, 0, 0, 0, 0, "Recalculate distance"); 
+                                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Distance:", *xco+18, *yco-60, 237, 18, &data->dist, 0.0, 100, 0.5, 0.5, "Radius of limiting sphere");
+                                       }
+                                       
+                                       /* disabled soft-distance controls... currently it doesn't work yet. It was intended to be used for soft-ik (see xsi-blog for details) */
+ #if 0
+                                       uiDefButBitS(block, TOG, LIMITDIST_USESOFT, B_CONSTRAINT_TEST, "Soft", *xco, *yco-82, 50, 18, &data->flag, 0, 24, 0, 0, "Enables soft-distance");
+                                       if (data->flag & LIMITDIST_USESOFT)
+                                               uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Soft-Distance:", *xco+50, *yco-82, 187, 18, &data->soft, 0.0, 100, 0.5, 0.5, "Distance surrounding radius when transforms should get 'delayed'");
+ #endif
+                               uiBlockEndAlign(block);
+                               
+                               uiDefButS(block, MENU, B_CONSTRAINT_TEST, "Limit Mode%t|Inside %x0|Outside %x1|Surface %x2", *xco+((width/2)-50), *yco-104, 100, 18, &data->mode, 0, 24, 0, 0, "Distances in relation to sphere of influence to allow");
+                       }
+                       break;
                case CONSTRAINT_TYPE_RIGIDBODYJOINT:
                        {
                                bRigidBodyJointConstraint *data = con->data;
@@@ -1750,6 -1785,7 +1787,7 @@@ static uiBlock *add_constraintmenu(voi
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCLIMIT, "Limit Location", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ROTLIMIT, "Limit Rotation", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_SIZELIMIT, "Limit Scale", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+       uiDefBut(block, BUTM, B_CONSTRAINT_ADD_DISTLIMIT, "Limit Distance", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
        
        uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
        
@@@ -1982,6 -2018,14 +2020,14 @@@ void do_constraintbuts(unsigned short e
                        BIF_undo_push("Add constraint");
                }
                break;
+       case B_CONSTRAINT_ADD_DISTLIMIT:
+               {
+                       con = add_new_constraint(CONSTRAINT_TYPE_DISTLIMIT);
+                       add_constraint_to_active(ob, con);
+                       
+                       BIF_undo_push("Add constraint");
+               }
+               break;
  
        default:
                break;
@@@ -2301,63 -2345,6 +2347,63 @@@ void do_object_panels(unsigned short ev
                if(ob->ipo) ob->ipo->showkey= (ob->ipoflag & OB_DRAWKEY)?1:0;
                allqueue(REDRAWVIEW3D, 0);
                break;
 +      case B_CLOTH_CLEARCACHEALL:
 +      {
 +              ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
 +              if(clmd)
 +              {
 +                      /* force freeing because user wants */
 +                      clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
 +                      
 +                      CFRA= 1;
 +                      update_for_newframe_muted();
 +                      DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); 
 +                      cloth_clear_cache(ob, clmd, 1); 
 +                      allqueue(REDRAWBUTSOBJECT, 0);
 +                      allqueue(REDRAWVIEW3D, 0);
 +              }       
 +      }
 +      break;  
 +      case B_CLOTH_CLEARCACHEFRAME:
 +      {
 +              ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
 +              if(clmd)
 +              {
 +                      /* force freeing because user wants */
 +                      clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
 +                      
 +                      cloth_clear_cache(ob, clmd, MAX2(1.0,G.scene->r.cfra)); 
 +                      // MAX2(1.0,G.scene->r.cfra + 1.0)
 +                      allqueue(REDRAWBUTSOBJECT, 0);
 +              }
 +      }
 +      break;  
 +      case B_CLOTH_CHANGEPREROLL:
 +      {
 +              ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
 +              if(clmd)
 +              {
 +                      if(clmd->sim_parms->cache)
 +                      {
 +                              CFRA= 1;
 +                              update_for_newframe_muted();
 +                              DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); 
 +                              allqueue(REDRAWBUTSOBJECT, 0);
 +                              allqueue(REDRAWVIEW3D, 0);
 +                      }
 +              }
 +      }
 +      break;  
 +      case B_CLOTH_RENEW:
 +      {
 +              ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
 +      
 +              if(clmd)
 +              {
 +                      clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
 +              }
 +      }
 +      break;
                
        default:
                if(event>=B_SELEFFECT && event<B_SELEFFECT+MAX_EFFECT) {
@@@ -3175,31 -3162,10 +3221,31 @@@ static void field_testTexture(char *nam
        }
        *idpp = 0;
  }
 +
 +/* Panel for collision */
 +static void object_collision__enabletoggle ( void *ob_v, void *arg2 )
 +{
 +      Object *ob = ob_v;
 +      ModifierData *md = modifiers_findByType ( ob, eModifierType_Collision );
 +
 +      if ( !md )
 +      {
 +              md = modifier_new ( eModifierType_Collision );
 +              BLI_addhead ( &ob->modifiers, md );
 +      }
 +      else
 +      {
 +              BLI_remlink ( &ob->modifiers, md );
 +              modifier_free ( md );
 +              allqueue(REDRAWBUTSEDIT, 0);
 +      }
 +}
 +
  /* Panels for particle interaction settings */
  static void object_panel_deflection(Object *ob)
  {
        uiBlock *block;
 +      uiBut *but;
  
        block= uiNewBlock(&curarea->uiblocks, "object_panel_deflection", UI_EMBOSS, UI_HELV, curarea->win);
        if(uiNewPanel(curarea, block, "Deflection", "Physics", 0, 0, 318, 204)==0) return;
        if(ob->pd && ob->type==OB_MESH) {
                PartDeflect *pd= ob->pd;
                
 -              uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",160,160,150,20, &pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision");
 +              but = uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",160,160,150,20, &pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision");
 +              uiButSetFunc(but, object_collision__enabletoggle, ob, NULL);
 +              
                if(pd->deflect) {
                        uiDefBut(block, LABEL, 0, "Particles",                  160,140,75,20, NULL, 0.0, 0, 0, 0, "");
                        uiDefButBitS(block, TOG, PDEFLE_KILL_PART, B_DIFF, "Kill",235,140,75,20, &pd->flag, 0, 0, 0, 0, "Kill collided particles");
@@@ -3490,7 -3454,7 +3536,7 @@@ static char sbsolvers[] = "Solver %t|RK
  /* SIF would have been candidate  .. well lack of time .. brecht is busy .. better make a stable version for peach now :) */
  static char sbsolvers[] = "SIF  semi implicit euler with fixed step size (worth a try with real stiff egdes)%x3|SOFT  step size controlled midpoint(1rst choice for real softbodies)%x0";
  #else
- static char sbsolvers[] = "SOFT  step size controlled midpoint(1rst choice for real softbodies)%x0";
+ static char sbsolvers[] = "RKCP correct physics (harder to get stable but usefull for education :)%x1|SOFT  step size controlled midpoint(1rst choice for real softbodies)%x0";
  #endif
  
  static void object_softbodies_collision(Object *ob)
  
                        uiBlockEndAlign(block);
                        /*SOLVER SETTINGS*/
-                       uiBlockBeginAlign(block);
                        /* done in another panel now*/
-                       /*
-                       uiDefButS(block, MENU, B_SOFTBODY_CHANGE, sbsolvers,10,100,50,20, &sb->solver_ID, 14.0, 0.0, 0, 0, "Select Solver");
-                       sb->solver_ID = 0; 
-                       switch (sb->solver_ID) {
-                       case 0:
-                       case 1:
-                               {adaptive_mode = 1; break;}
-                       case 3:
-                               {adaptive_mode = 0; break;}
-                       default: printf("SB_solver?\n"); // should never happen
-                       }
-                       if(adaptive_mode){
-                               uiDefButF(block, NUM, B_DIFF, "Error Lim:",     60,100,120,20, &sb->rklimit , 0.001, 10.0, 10, 0, "The Runge-Kutta ODE solver error limit, low value gives more precision, high values speed");
-                               uiDefButBitS(block, TOG, SBSO_OLDERR, B_DIFF,"O", 180,100,20,20, &sb->solverflags,  0,  0, 0, 0, "Old Error Calculation");
-                               uiDefButS(block, NUM, B_DIFF, "Fuzzy:", 200,100,90,20, &sb->fuzzyness,  1.00,  100.0, 10, 0, "Fuzzyness while on collision, high values make collsion handling faster but less stable");
-                               uiDefButBitS(block, TOG, SBSO_MONITOR, B_DIFF,"M", 290,100,20,20, &sb->solverflags,  0,  0, 0, 0, "Turn on SB diagnose console prints");
-                               uiBlockEndAlign(block);
-                               uiDefButS(block, NUM, B_DIFF, "MinS:", 10,80,100,20, &sb->minloops,  0.00,  30000.0, 10, 0, "Minimal # solver steps/frame ");
-                               uiDefButS(block, NUM, B_DIFF, "MaxS:", 110,80,100,20, &sb->maxloops,  0.00,  30000.0, 10, 0, "Maximal # solver steps/frame ");
-                               uiDefButS(block, NUM, B_DIFF, "Choke:", 210,80,100,20, &sb->choke, 0.00,  100.0, 10, 0, "'Viscosity' inside collision target ");
-                       } 
-                       else{
-                               uiBlockEndAlign(block);
-                               uiBlockBeginAlign(block);
-                               uiDefButS(block, NUM, B_DIFF, "Fuzzy:", 210,100,90,20, &sb->fuzzyness,  1.00,  100.0, 10, 0, "Fuzzyness while on collision, high values make collsion handling faster but less stable");
-                               uiDefButBitS(block, TOG, SBSO_MONITOR, B_DIFF,"M", 290,100,20,20, &sb->solverflags,  0,  0, 0, 0, "Turn on SB diagnose console prints");
-                               uiBlockEndAlign(block);
-                               uiDefButS(block, NUM, B_DIFF, "Steps:", 10,80,100,20, &sb->minloops,  1.00,  30000.0, 10, 0, "Solver steps/frame ");
-                               uiDefButS(block, NUM, B_DIFF, "Choke:", 210,80,100,20, &sb->choke, 0.00,  100.0, 10, 0, "'Viscosity' inside collision target ");
-                       }
-                       */
                }
                /* OTHER OBJECTS COLLISION STUFF */
                if (ob->type==OB_MESH){
@@@ -3640,12 -3569,12 +3651,12 @@@ static void object_softbodies_solver(Ob
        static int val;
        short *softflag=&ob->softflag, psys_cur=0, adaptive_mode=0;
        int ob_has_hair=psys_ob_has_hair(ob);
-     if(!_can_softbodies_at_all(ob)) return;
+       if(!_can_softbodies_at_all(ob)) return;
        block= uiNewBlock(&curarea->uiblocks, "object_softbodies_solver", UI_EMBOSS, UI_HELV, curarea->win);
        if(uiNewPanel(curarea, block, "Soft Body Solver", "Physics", 651, 0, 318, 204)==0) return;
  
        uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
-     /* doubt that is really needed here but for now */ 
+       /* doubt that is really needed here but for now */ 
        if(ob_has_hair) {
                if(PE_get_current_num(ob) >= 0) {
                        ParticleSystem *psys = PE_get_current(ob);
                        /*SOLVER SETTINGS*/
                        uiBlockBeginAlign(block);
                        uiDefBut(block, LABEL, 0, "Solver select",10,200,300,20, NULL, 0.0, 0, 0, 0, ""); 
-                       uiDefButS(block, MENU, B_SOFTBODY_CHANGE, sbsolvers,10,180,300,20, &sb->solver_ID, 14.0, 0.0, 0, 0, "Select Solver (choose 1 of 1 i was working on some other but failed *sigh* BM) ");
+                       uiDefButS(block, MENU, B_SOFTBODY_CHANGE, sbsolvers,10,180,300,20, &sb->solver_ID, 14.0, 0.0, 0, 0, "Select Solver");
                        uiBlockEndAlign(block);
-                       
                        /*some have adapive step size - some not*/
-                       sb->solver_ID = 0; /* ugly hack to prepare peach freeze */
                        switch (sb->solver_ID) {
                        case 0:
                        case 1:
                        }
                        if(adaptive_mode){
                                uiBlockBeginAlign(block);
-                           uiDefBut(block, LABEL, 0, "Step size controls",10,160,300,20, NULL, 0.0, 0, 0, 0, "");
+                               uiDefBut(block, LABEL, 0, "Step size controls",10,160,300,20, NULL, 0.0, 0, 0, 0, "");
                                uiDefButF(block, NUM, B_DIFF, "Error Lim:",     10,140,280,20, &sb->rklimit , 0.001, 10.0, 10, 0, "The Runge-Kutta ODE solver error limit, low value gives more precision, high values speed");
                                uiDefButBitS(block, TOG, SBSO_OLDERR, B_DIFF,"V", 290,140,20,20, &sb->solverflags,  0,  0, 0, 0, "Use velocities for automagic step sizes");
                                uiDefButS(block, NUM, B_DIFF, "MinS:", 10,120,150,20, &sb->minloops,  0.00,  30000.0, 10, 0, "Minimal # solver steps/frame ");
                                uiBlockEndAlign(block);
  
                                uiBlockBeginAlign(block);
-                       uiDefBut(block, LABEL, 0, "Collision helpers",10,100,300,20, NULL, 0.0, 0, 0, 0, "");
+                               uiDefBut(block, LABEL, 0, "Collision helpers",10,100,300,20, NULL, 0.0, 0, 0, 0, "");
                                uiDefButS(block, NUM, B_DIFF, "Choke:", 10,80,150,20, &sb->choke, 0.00,  100.0, 10, 0, "'Viscosity' inside collision target ");
                                uiDefButS(block, NUM, B_DIFF, "Fuzzy:", 160,80,150,20, &sb->fuzzyness,  1.00,  100.0, 10, 0, "Fuzzyness while on collision, high values make collsion handling faster but less stable");
                                uiBlockEndAlign(block);
-                               
                                uiBlockBeginAlign(block);
                                uiDefBut(block, LABEL, 0, "Diagnosis stuff",10,60,300,20, NULL, 0.0, 0, 0, 0, "");
                                uiDefButBitS(block, TOG, SBSO_MONITOR, B_DIFF,"Print Performance to Console", 10,40,300,20, &sb->solverflags,  0,  0, 0, 0, "Turn on SB diagnose console prints");                              
                                uiDefButS(block, NUM, B_DIFF, "Choke:", 210,80,100,20, &sb->choke, 0.00,  100.0, 10, 0, "'Viscosity' inside collision target ");
                        }
  
-       uiBlockEndAlign(block);
+                       uiBlockEndAlign(block);
  
                }
-               //uiDefBut(block, LABEL, 0, "",10,10,1,2, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
        }
        uiBlockEndAlign(block);
  }
@@@ -3850,7 -3777,7 +3859,7 @@@ static void object_softbodies(Object *o
                        uiBlockBeginAlign(block);
                        uiDefButF(block, NUM, B_DIFF, "Friction:", 10, 170,150,20, &sb->mediafrict, 0.0, 50.0, 10, 0, "General media friction for point movements");
                        uiDefButF(block, NUM, B_DIFF, "Mass:",     160, 170,150,20, &sb->nodemass , 0.001, 50000.0, 10, 0, str);
-                       uiDefButF(block, NUM, B_DIFF, "Grav:",     10,150,150,20, &sb->grav , 0.0, 10.0, 10, 0, "Apply gravitation to point movement");
+                       uiDefButF(block, NUM, B_DIFF, "Grav:",     10,150,150,20, &sb->grav , -10.0, 10.0, 10, 0, "Apply gravitation to point movement");
                        uiDefButF(block, NUM, B_DIFF, "Speed:",    160,150,150,20, &sb->physics_speed , 0.01, 100.0, 10, 0, "Tweak timing for physics to control frequency and speed");
                        uiBlockEndAlign(block);
  
@@@ -4110,7 -4037,7 +4119,7 @@@ static void object_panel_particle_extra
  
                uiBlockBeginAlign(block);
                
-               uiDefButS(block, MENU, B_PART_REDRAW, "Attribute%t|TanRot%x10|TanVel%x9|Size%x8|RoughE%x7|Rough2%x6|Rough1%x5|Kink%x4|Clump%x3|Length%x2|Velocity%x1|Density%x0", butx,(buty-=buth),butw-40,buth, &vgnum, 14.0, 0.0, 0, 0, "Attribute effected by vertex group");
+               uiDefButS(block, MENU, B_PART_REDRAW, "Attribute%t|Effector%x11|TanRot%x10|TanVel%x9|Size%x8|RoughE%x7|Rough2%x6|Rough1%x5|Kink%x4|Clump%x3|Length%x2|Velocity%x1|Density%x0", butx,(buty-=buth),butw-40,buth, &vgnum, 14.0, 0.0, 0, 0, "Attribute effected by vertex group");
                but=uiDefButBitS(block, TOG, (1<<vgnum), B_PART_REDRAW, "Neg",  butx+butw-40,buty,40,buth, &psys->vg_neg, 0, 0, 0, 0, "Negate the effect of the vertex group");
                uiButSetFunc(but, particle_set_vg, (void *)ob, (void *)(&vgnum));
                
@@@ -5028,313 -4955,6 +5037,313 @@@ 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);
 +              
 +              allqueue(REDRAWBUTSEDIT, 0);
 +      }
 +      else {
 +              Object *ob = ob_v;
 +              ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth);
 +      
 +              if (!md)
 +                      return;
 +
 +              BLI_remlink(&ob->modifiers, md);
 +
 +              modifier_free(md);
 +
 +              BIF_undo_push("Del modifier");
 +              
 +              ob->softflag |= OB_SB_RESET;
 +              allqueue(REDRAWBUTSEDIT, 0);
 +              allqueue(REDRAWVIEW3D, 0);
 +              allqueue(REDRAWIMAGE, 0);
 +              allqueue(REDRAWOOPS, 0);
 +              DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 +              object_handle_update(ob);
 +              countall();
 +      }
 +}
 +
 +
 +static void object_panel_cloth(Object *ob)
 +{
 +      uiBlock *block;
 +      uiBut *but;
 +      static int val, val2;
 +      ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
 +      
 +      block= uiNewBlock(&curarea->uiblocks, "object_cloth", UI_EMBOSS, UI_HELV, curarea->win);
 +      if(uiNewPanel(curarea, block, "Cloth ", "Physics", 640, 0, 318, 204)==0) return;
 +      uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
 +      
 +      val = (clmd ? 1:0);
 +
 +      but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Cloth",  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)
 +      {
 +              int defCount;
 +              char *clvg1, *clvg2;
 +              char clmvg [] = "Vertex Groups%t|";
 +
 +              val2=0;
 +              
 +              /* 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 coefficient (higher = less smaller but more big wrinkles)");
 +              uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:",           10,150,150,20, &clmd->sim_parms->stepsPerFrame, 4.0, 100.0, 5, 0, "Quality of the simulation (higher=better=slower)");
 +
 +              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, "Air has normaly some thickness which slows falling things down");
 +              
 +              uiDefBut(block, LABEL, 0, "Gravity:",  10,100,60,20, NULL, 0.0, 0, 0, 0, "");
 +              
 +              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, "Pinning of cloth", 10,70,150,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) && (BLI_countlist (&ob->defbase) > 0))
 +              {
 +                      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;
 +                              }
 +                              else
 +                              {
 +                                      if(!clmd->sim_parms->vgroup_mass)
 +                                              clmd->sim_parms->vgroup_mass = 1;
 +                                      else if(clmd->sim_parms->vgroup_mass > defCount)
 +                                              clmd->sim_parms->vgroup_mass = defCount;
 +                              }
 +                                                      
 +                              sprintf (clvg2, "%s%s", clmvg, clvg1);
 +                              
 +                              uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2,    160,70,150,20, &clmd->sim_parms->vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups");
 +                              MEM_freeN (clvg1);
 +                              MEM_freeN (clvg2);
 +                      }
 +                      
 +                      uiDefButF(block, NUM, B_CLOTH_RENEW, "Pin Stiff:",      10,50,150,20, &clmd->sim_parms->goalspring, 0.0, 500.0, 10, 0, "Pin (vertex target position) spring stiffness");
 +                      uiDefBut(block, LABEL, 0, " ",  160,50,150,20, NULL, 0.0, 0, 0, 0, "");
 +                      /*
 +                      // nobody is changing these ones anyway
 +                      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");
 +                      */
 +              }
 +              else if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
 +              {
 +                      uiDefBut(block, LABEL, 0, " ",  160,70,150,20, NULL, 0.0, 0, 0, 0, "");
 +                      uiDefBut(block, LABEL, 0, "No vertex group for pinning available.",  10,50,300,20, NULL, 0.0, 0, 0, 0, "");
 +              }
 +              
 +              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); 
 +              */
 +      }
 +      
 +      uiBlockEndAlign(block);
 +      
 +      uiBlockEndAlign(block);
 +}
 +
 +static void object_panel_cloth_II(Object *ob)
 +{
 +      uiBlock *block;
 +      ClothModifierData *clmd = NULL;
 +
 +      block= uiNewBlock(&curarea->uiblocks, "object_cloth_II", UI_EMBOSS, UI_HELV, curarea->win);
 +      uiNewPanelTabbed("Cloth ", "Physics");
 +      if(uiNewPanel(curarea, block, "Cloth Cache/Collisions", "Physics", 651, 0, 318, 204)==0) return;
 +
 +      uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
 +      
 +      clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
 +      
 +      if(clmd)
 +      {       
 +              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");
 +              
 +              uiDefBut(block, LABEL, 0, "",10,140,300,20, NULL, 0.0, 0, 0, 0, "");
 +              
 +              if (!G.relbase_valid)
 +              {
 +                      uiDefBut(block, LABEL, 0, "Cache deactivated until file is saved.",  10,120,300,20, NULL, 0.0, 0, 0, 0, "");
 +                      uiDefBut(block, LABEL, 0, " ",  10,100,300,40, NULL, 0.0, 0, 0, 0, "");
 +              }
 +              else
 +              {
 +                      uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT, REDRAWVIEW3D, "Protect Cache & Enable Cache Editing",   10,120,300,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Protect cache from automatic freeing when scene changed. This also enabled the cache beeing edited in editmode.");
 +                      
 +                      uiDefBut(block, LABEL, 0, "Clear cache:",  10,100,90,20, NULL, 0.0, 0, 0, 0, "");
 +                      uiDefBut(block, BUT, B_CLOTH_CLEARCACHEALL, "All", 100, 100,100,20, NULL, 0.0, 0.0, 10, 0, "Free ALL cloth cache without preroll");
 +                      uiDefBut(block, BUT, B_CLOTH_CLEARCACHEFRAME, "From next frame", 200, 100,110,20, NULL, 0.0, 0.0, 10, 0, "Free cloth cache starting from next frame");  
 +                      uiDefBut(block, LABEL, 0, " ",  10,80,300,20, NULL, 0.0, 0, 0, 0, "");
 +              }
 +
 +              /*
 +              TODO: implement this again in cloth!
 +              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, "");
 +              */
 +
 +              uiDefButBitI(block, TOG, CLOTH_COLLSETTINGS_FLAG_ENABLED, REDRAWVIEW3D, "Enable collisions",    10,60,150,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable collisions with this object");
 +              if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED)
 +              {
 +                      uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:",      160,60,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in");
 +                      uiDefButS(block, NUM, REDRAWBUTSOBJECT, "Collision Quality:",      10,40,300,20, &clmd->coll_parms->loop_count, 1.0, 100.0, 1.0, 0, "How many collision iterations should be done. (higher = better = slower), je be changed for each frame");
 +              }
 +              else
 +                      uiDefBut(block, LABEL, 0, "",160,60,150,20, NULL, 0.0, 0, 0, 0, "");    
 +      }
 +      
 +      uiBlockEndAlign(block);
 +      
 +}
 +
 +static void object_panel_cloth_III(Object *ob)
 +{
 +      uiBlock *block;
 +      ClothModifierData *clmd = NULL;
 +
 +      block= uiNewBlock(&curarea->uiblocks, "object_cloth_III", UI_EMBOSS, UI_HELV, curarea->win);
 +      uiNewPanelTabbed("Cloth ", "Physics");
 +      if(uiNewPanel(curarea, block, "Cloth Advanced", "Physics", 651, 0, 318, 204)==0) return;
 +
 +      uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
 +      
 +      clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
 +      
 +      if(clmd)
 +      {
 +              int defCount;
 +              char *clvg1, *clvg2;
 +              char clmvg [] = "Vertex Groups%t|None%x0|";
 +              char clmvg2 [] = "Vertex Groups%t|None%x0|";
 +              
 +              uiDefButI(block, NUM, B_DIFF, "Autoprotect Cache From:",10,160,300,20, &clmd->sim_parms->autoprotect, 0, MAXFRAME, 1, 0, "Frame on which the simulation gets cache protection enabled automatically (To prevent accidently cleaning it).");
 +                              
 +              uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_SCALING, REDRAWVIEW3D, "Enable stiffness scaling",10,130,300,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "If enabled, stiffness can be scaled along a weight painted vertex group.");
 +              
 +              if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING)&& (BLI_countlist (&ob->defbase) > 0))
 +              {       
 +                      uiDefBut(block, LABEL, 0, "StructStiff VGroup:",10,110,150,20, NULL, 0.0, 0, 0, 0, "");
 +                      uiDefBut(block, LABEL, 0, "BendStiff VGroup:",160,110,150,20, NULL, 0.0, 0, 0, 0, "");
 +                      
 +                      defCount = sizeof (clmvg);
 +                      clvg1 = get_vertexgroup_menustr (ob);
 +                      clvg2 = MEM_callocN (strlen (clvg1) + 1 + defCount, "clothVgST");
 +                      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_struct = 0;
 +                      }
 +                      else
 +                      {
 +                              if(clmd->sim_parms->vgroup_struct > defCount)
 +                                      clmd->sim_parms->vgroup_struct = 0;
 +                      }
 +                                              
 +                      sprintf (clvg2, "%s%s", clmvg, clvg1);
 +                      
 +                      uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2,    10,90,150,20, &clmd->sim_parms->vgroup_struct, 0, defCount, 0, 0, "Browses available vertex groups");
 +                      MEM_freeN (clvg1);
 +                      MEM_freeN (clvg2);
 +                      
 +                      defCount = sizeof (clmvg);
 +                      clvg1 = get_vertexgroup_menustr (ob);
 +                      clvg2 = MEM_callocN (strlen (clvg1) + 1 + defCount, "clothVgBD");
 +                      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_bend = 0;
 +                      }
 +                      else
 +                      {
 +                              if(clmd->sim_parms->vgroup_bend > defCount)
 +                                      clmd->sim_parms->vgroup_bend = 0;
 +                      }
 +                                              
 +                      sprintf (clvg2, "%s%s", clmvg2, clvg1);
 +                      
 +                      uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 160,90,150,20, &clmd->sim_parms->vgroup_bend, 0, defCount, 0, 0, "Browses available vertex groups");
 +                      MEM_freeN (clvg1);
 +                      MEM_freeN (clvg2);
 +                      
 +                      uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff Max:",10,70,150,20, &clmd->sim_parms->max_struct, clmd->sim_parms->structural, 1000.0, 0.01f, 0, "Maximum structural stiffness value");
 +                      
 +                      uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff Max:",160,70,150,20, &clmd->sim_parms->max_bend, clmd->sim_parms->bending, 1000.0, 0.01f, 0, "Maximum bending stiffness value");
 +
 +              }
 +              else if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING)
 +              {
 +                      uiDefBut(block, LABEL, 0, " ",  10,110,300,20, NULL, 0.0, 0, 0, 0, "");
 +                      uiDefBut(block, LABEL, 0, "No vertex group for pinning available.",  10,90,300,20, NULL, 0.0, 0, 0, 0, "");
 +              }
 +      
 +              
 +              
 +      }
 +      
 +      uiBlockEndAlign(block);
 +      
 +}
 +
  void object_panels()
  {
        Object *ob;
@@@ -5364,9 -4984,6 +5373,9 @@@ void physics_panels(
                object_softbodies(ob);
                object_softbodies_collision(ob);
                object_softbodies_solver(ob);
 +              object_panel_cloth(ob);
 +              object_panel_cloth_II(ob);
 +              object_panel_cloth_III(ob);
                object_panel_fluidsim(ob);
        }
  }
index cb1ed4c3e5aa9ba9af68a14bbfcb07d37015f502,4e90fbac5acd12758b930ffe4d9683a5f344ca11..a7b8400fb9db26748df81dd693ece52ba179f667
  #include "BKE_customdata.h"
  #include "BKE_blender.h"
  #include "BKE_booleanops.h"
 +#include "BKE_cloth.h"
  #include "BKE_curve.h"
  #include "BKE_displist.h"
  #include "BKE_depsgraph.h"
@@@ -1760,11 -1759,6 +1760,11 @@@ void exit_editmode(int flag)  /* freedat
                sbObjectToSoftbody(ob);
        }
        
 +      if(modifiers_isClothEnabled(ob)) {
 +              ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
 +              clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
 +      }
 +      
        if(ob->type==OB_MESH && get_mesh(ob)->mr)
                multires_edge_level_update(ob, get_mesh(ob));
        
@@@ -5148,7 -5142,7 +5148,7 @@@ void selectlinks_menu(void
        /* If you modify this menu, please remember to update view3d_select_linksmenu
         * in header_view3d.c and the menu in toolbox.c
         */
-       nr= pupmenu("Select Linked%t|Object Ipo%x1|ObData%x2|Material%x3|Texture%x4|DupliGroup%x5");
+       nr= pupmenu("Select Linked%t|Object Ipo%x1|ObData%x2|Material%x3|Texture%x4|DupliGroup%x5|ParticleSystem%x6");
        
        if (nr <= 0) return;
        
@@@ -5171,6 -5165,7 +5171,7 @@@ void selectlinks(int nr
         * Current Material: 3
         * Current Texture: 4
         * DupliGroup: 5
+        * PSys: 6
         */
        
        
        else if(nr==5) {
                if(ob->dup_group==NULL) return;
        }
+       else if(nr==6) {
+               if(ob->particlesystem.first==NULL) return;
+       }
        else return;
        
        base= FIRSTBASE;
                                                                if(tex==mat1->mtex[b]->tex) {
                                                                        base->flag |= SELECT;
                                                                        changed = 1;
+                                                                       break;
                                                                }
                                                        }
                                                }
                                         changed = 1;
                                }
                        }
+                       else if(nr==6) {
+                               /* loop through other, then actives particles*/
+                               ParticleSystem *psys;
+                               ParticleSystem *psys_act;
+                               
+                               for(psys=base->object->particlesystem.first; psys; psys=psys->next) {
+                                       for(psys_act=ob->particlesystem.first; psys_act; psys_act=psys_act->next) {
+                                               if (psys->part == psys_act->part) {
+                                                       base->flag |= SELECT;
+                                                       changed = 1;
+                                                       break;
+                                               }
+                                       }
+                                       
+                                       if (base->flag & SELECT) {
+                                               break;
+                                       }
+                               }
+                       }
                        base->object->flag= base->flag;
                }
                base= base->next;
@@@ -5580,17 -5598,9 +5604,9 @@@ void mirrormenu(void
        if(G.f & G_PARTICLEEDIT) {
                PE_mirror_x(0);
        }
-       else if (G.obedit==0) {
-               mode=pupmenu("Mirror Axis %t|X Local%x4|Y Local%x5|Z Local%x6|");
-               if (mode==-1) return; /* return */
-               Mirror(mode); /* separating functionality from interface | call*/
-       }
        else {
-               mode=pupmenu("Mirror Axis %t|X Global%x1|Y Global%x2|Z Global%x3|%l|X Local%x4|Y Local%x5|Z Local%x6|%l|X View%x7|Y View%x8|Z View%x9|");
-               if (mode==-1) return; /* return */
-               Mirror(mode); /* separating functionality from interface | call*/
+               initTransform(TFM_MIRROR, CTX_NO_PET);
+               Transform();
        }
  }