diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py
index 6b72ef1..c89e36b 100644
--- a/release/scripts/startup/bl_ui/__init__.py
+++ b/release/scripts/startup/bl_ui/__init__.py
@@ -37,6 +37,7 @@ _modules = [
     "properties_data_mesh",
     "properties_data_metaball",
     "properties_data_modifier",
+    "properties_data_muscle",
     "properties_data_speaker",
     "properties_game",
     "properties_mask_common",
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index efc430d..dd4b1bb 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1225,6 +1225,19 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
 
         col.prop(md, "material_offset", text="Material Offset")
 
+    def MUSCLE(self, layout, ob, md):
+        split = layout.split()
+        col = split.column()
+        col.prop(md, "muscle", text="")
+        col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+        col.prop(md, "contraction")
+		
+    def MASSSPRING(self, layout, ob, md):
+        split = layout.split()
+        col = split.column()
+        col.prop(md, "factor")
+        col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+
 
 if __name__ == "__main__":  # only for live edit.
     bpy.utils.register_module(__name__)
diff --git a/release/scripts/startup/bl_ui/properties_data_muscle.py b/release/scripts/startup/bl_ui/properties_data_muscle.py
new file mode 100644
index 0000000..61209e1
--- /dev/null
+++ b/release/scripts/startup/bl_ui/properties_data_muscle.py
@@ -0,0 +1,79 @@
+# ##### BEGIN GPL 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.
+#
+#  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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+import bpy
+from bpy.types import Panel, Menu
+from rna_prop_ui import PropertyPanel
+
+
+class MuscleButtonsPanel():
+    bl_space_type = 'PROPERTIES'
+    bl_region_type = 'WINDOW'
+    bl_context = "data"
+
+    @classmethod
+    def poll(cls, context):
+        engine = context.scene.render.engine
+        return context.object.type == 'MUSCLE' # and (engine in cls.COMPAT_ENGINES)
+
+
+class DATA_PT_context_muscle(MuscleButtonsPanel, Panel):
+    bl_label = ""
+    bl_options = {'HIDE_HEADER'}
+    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+
+    def draw(self, context):
+        layout = self.layout
+
+        ob = context.object
+        muscle = context.muscle
+        space = context.space_data
+
+        split = layout.split(percentage=0.65)
+        if ob:
+            split.template_ID(ob, "data")
+            split.separator()
+        elif muscle:
+            split.template_ID(space, "pin_id")
+            split.separator()
+
+class DATA_PT_muscle_test_value(MuscleButtonsPanel, Panel):
+    bl_label = "Muscle properties"
+    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+
+    def draw(self, context):
+        layout = self.layout
+
+        split = layout.split()
+        col = split.column()
+        col.prop(context.muscle, "type")
+        if context.muscle.type == "LINEAR":
+            col.prop(context.muscle, "omega")
+        col.prop(context.muscle, "fs")
+        col.prop(context.muscle, "ff")
+        if context.muscle.type == "LINEAR":
+            col.prop(context.muscle, "k")
+            col.prop(context.muscle, "wrinkle_n")
+            col.prop(context.muscle, "wrinkle_h")
+        if context.muscle.type == "SPHINCTER":
+            col.prop(context.muscle, "r")
+            col.prop(context.muscle, "h")
+
+if __name__ == "__main__":  # only for live edit.
+    bpy.utils.register_module(__name__)
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 500c281..93f06c0 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -71,7 +71,7 @@ void id_clear_lib_data(struct Main *bmain, struct ID *id);
 
 struct ListBase *which_libbase(struct Main *mainlib, short type);
 
-#define MAX_LIBARRAY    35
+#define MAX_LIBARRAY    36
 int set_listbasepointers(struct Main *main, struct ListBase *lb[MAX_LIBARRAY]);
 
 void BKE_libblock_free(struct Main *bmain, void *idv);
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index ec654ea..50b98a1 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -94,6 +94,7 @@ typedef struct Main {
 	ListBase movieclip;
 	ListBase mask;
 	ListBase linestyle;
+	ListBase muscles;
 
 	char id_tag_update[256];
 
@@ -109,7 +110,7 @@ typedef struct Main {
 #define MAIN_VERSION_OLDER(main, ver, subver) \
 	((main)->versionfile < (ver) || (main->versionfile == (ver) && (main)->subversionfile < (subver)))
 
-	
+	void *BKE_muscle_add(Main *bmain, const char *name);
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c
index 1b7a03e..dc99dd1 100644
--- a/source/blender/blenkernel/intern/idcode.c
+++ b/source/blender/blenkernel/intern/idcode.c
@@ -70,6 +70,7 @@ static IDType idtypes[] = {
 	{ ID_MC,     "MovieClip",        "movieclips",      IDTYPE_FLAGS_ISLINKABLE },
 	{ ID_ME,     "Mesh",             "meshes",          IDTYPE_FLAGS_ISLINKABLE },
 	{ ID_MSK,    "Mask",             "masks",           IDTYPE_FLAGS_ISLINKABLE },
+	{ ID_MU,     "Muscle",           "muscles",         IDTYPE_FLAGS_ISLINKABLE },
 	{ ID_NT,     "NodeTree",         "node_groups",     IDTYPE_FLAGS_ISLINKABLE },
 	{ ID_OB,     "Object",           "objects",         IDTYPE_FLAGS_ISLINKABLE },
 	{ ID_PA,     "ParticleSettings", "particles",       0                       },
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index b49eee3..2e49b11 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -520,6 +520,8 @@ ListBase *which_libbase(Main *mainlib, short type)
 			return &(mainlib->palettes);
 		case ID_PC:
 			return &(mainlib->paintcurves);
+		case ID_MU:
+			return &(mainlib->muscles);
 	}
 	return NULL;
 }
@@ -617,6 +619,8 @@ int set_listbasepointers(Main *main, ListBase **lb)
 	lb[a++] = &(main->wm);
 	lb[a++] = &(main->movieclip);
 	lb[a++] = &(main->mask);
+
+	lb[a++] = &(main->muscles);
 	
 	lb[a] = NULL;
 
@@ -746,6 +750,9 @@ static ID *alloc_libblock_notest(short type)
 		case ID_PC:
 			id = MEM_callocN(sizeof(PaintCurve), "Paint Curve");
 			break;
+		case ID_MU:
+			id = MEM_callocN(sizeof(Muscle), "Muscle");
+			break;
 	}
 	return id;
 }
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index f2400c9..ead4636 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -896,6 +896,24 @@ bool BKE_object_exists_check(Object *obtest)
 	return false;
 }
 
+
+/*MUSCLES*/
+void *BKE_muscle_add(Main *bmain, const char *name)
+{
+	Muscle *m;
+
+	m = BKE_libblock_alloc(bmain, ID_MU, name);
+	m->wrinkle_n = 2;
+	m->wrinkle_h = 0.5;
+	m->K = 1.0f;
+	m->Ff = 1.0f;
+	m->Fs = 0.0f;
+	m->omega = M_PI_4;
+
+	return m;
+}
+/*ENDMUSCLES*/
+
 /* *************************************************** */
 
 void *BKE_object_obdata_add_from_type(Main *bmain, int type)
@@ -912,6 +930,7 @@ void *BKE_object_obdata_add_from_type(Main *bmain, int type)
 		case OB_ARMATURE:  return BKE_armature_add(bmain, "Armature");
 		case OB_SPEAKER:   return BKE_speaker_add(bmain, "Speaker");
 		case OB_EMPTY:     return NULL;
+		case OB_MUSCLE:    return BKE_muscle_add(bmain, "Muscle");
 		default:
 			printf("BKE_object_obdata_add_from_type: Internal error, bad type: %d\n", type);
 			return NULL;
@@ -932,6 +951,7 @@ static const char *get_obdata_defname(int type)
 		case OB_ARMATURE: return DATA_("Armature");
 		case OB_SPEAKER: return DATA_("Speaker");
 		case OB_EMPTY: return DATA_("Empty");
+		case OB_MUSCLE: return DATA_("Muscle");
 		default:
 			printf("get_obdata_defname: Internal error, bad type: %d\n", type);
 			return DATA_("Empty");
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index dd947ae..f9a85b9 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1898,7 +1898,6 @@ static void direct_link_script(FileData *UNUSED(fd), Script *script)
 	SCRIPT_SET_NULL(script);
 }
 
-
 /* ************ READ PACKEDFILE *************** */
 
 static PackedFile *direct_link_packedfile(FileData *fd, PackedFile *oldpf)
@@ -4244,6 +4243,12 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
 	}
 }
 
+/* ************ READ MUSCLE ***************** */
+
+static void direct_link_muscle(FileData *fd, Muscle *lt)
+{
+}
+
 /* ************ READ LATTICE ***************** */
 
 static void lib_link_latt(FileData *fd, Main *main)
@@ -4852,6 +4857,10 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
 			}
 			lmd->cache_system = NULL;
 		}
+		else if (md->type == eModifierType_Muscle) {
+			MuscleModifierData *mmd = (MuscleModifierData *)md;
+			mmd->muscle = newdataadr(fd, mmd->muscle);
+		}
 	}
 }
 
@@ -7284,6 +7293,7 @@ static const char *dataname(short id_code)
 		case ID_MC: return "Data from MC";
 		case ID_MSK: return "Data from MSK";
 		case ID_LS: return "Data from LS";
+		case ID_MU: return "Data from MU";
 	}
 	return "Data from Lib Block";
 	
@@ -7470,6 +7480,9 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
 		case ID_PC:
 			direct_link_paint_curve(fd, (PaintCurve *)id);
 			break;
+		case ID_MU:
+			direct_link_muscle(fd, (Muscle *)id);
+			break;
 	}
 	
 	oldnewmap_free_unused(fd->datamap);
@@ -8864,6 +8877,9 @@ void BLO_expand_main(void *fdhandle, Main *mainvar)
 					case ID_LS:
 						expand_linestyle(fd, mainvar, (FreestyleLineStyle *)id);
 						break;
+					case ID_MU:
+						printf("NOT IMPLEMENTED, EXPAND_MUSCLE!!!!");
+						break;
 					}
 					
 					do_it = true;
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 59f1265..bbbe5f4 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -3073,6 +3073,20 @@ static void write_paintcurves(WriteData *wd, ListBase *idbase)
 	}
 }
 
+static void write_muscles(WriteData *wd, ListBase *idbase)
+{
+	Muscle *m;
+
+	for (m = idbase->first; m; m = m->id.next) {
+		if (m->id.us > 0 || wd->current) {
+			writestruct(wd, ID_MU, "Muscle", 1, m);
+
+			//writestruct(wd, DATA, "PaintCurvePoint", pc->tot_points, pc->points);
+			if (m->id.properties) IDP_WriteProperty(m->id.properties, wd);
+		}
+	}
+}
+
 static void write_scripts(WriteData *wd, ListBase *idbase)
 {
 	Script *script;
@@ -3552,6 +3566,7 @@ static int write_file_handle(
 	write_scripts  (wd, &mainvar->script);
 	write_gpencils (wd, &mainvar->gpencil);
 	write_linestyles(wd, &mainvar->linestyle);
+	write_muscles  (wd, &mainvar->muscles);
 	write_libraries(wd,  mainvar->next);
 
 	if (write_user_block) {
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 24dcf85..8a27f61 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -2404,3 +2404,47 @@ void OBJECT_OT_join_shapes(wmOperatorType *ot)
 	/* flags */
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 }
+
+/* MUSCLES */
+
+static int object_muscle_add_exec(bContext *C, wmOperator *op)
+{
+	Object *ob;
+	Object *ob2;
+	//int type = RNA_enum_get(op->ptr, "type");
+	unsigned int layer;
+	float loc[3], rot[3];
+
+	WM_operator_view3d_unit_defaults(C, op);
+	if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, &layer, NULL))
+		return OPERATOR_CANCELLED;
+
+	ob = ED_object_add_type(C, OB_MUSCLE, loc, rot, false, layer);
+	loc[0] += 1;
+	ob2 = ED_object_add_type(C, OB_MUSCLE, loc, rot, false, layer);
+	//((Muscle*)ob->data)->test_value = RNA_float_get(op->ptr, "test_value");
+	ob2->parent = ob;
+
+	//BKE_object_empty_draw_type_set(ob, type);
+	//BKE_object_obdata_size_init(ob, RNA_float_get(op->ptr, "radius"));
+	//printf("Hallo!\n");
+
+	return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_muscle_add(struct wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Add muscle";
+	ot->description = "Add new muscle";
+	ot->idname = "OBJECT_OT_muscle_add";
+
+	/* api callbacks */
+	ot->exec = object_muscle_add_exec;
+	ot->poll = ED_operator_objectmode;
+
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+	//RNA_def_float(ot->srna, "test_value", 1.0, 0.0, 1.0, "Test value", "Object name to add", 0.0, 1.0);
+	ED_object_add_generic_props(ot, true);
+}
\ No newline at end of file
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 6fa3caa..b0251d7 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -266,5 +266,7 @@ void OBJECT_OT_lod_remove(struct wmOperatorType *ot);
 /* object_random.c */
 void OBJECT_OT_vertex_random(struct wmOperatorType *ot);
 
+void OBJECT_OT_muscle_add(struct wmOperatorType *ot);
+
 #endif /* __OBJECT_INTERN_H__ */
 
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index bef64fe..fca0fe5 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -250,6 +250,8 @@ void ED_operatortypes_object(void)
 	WM_operatortype_append(OBJECT_OT_lod_remove);
 
 	WM_operatortype_append(OBJECT_OT_vertex_random);
+
+	WM_operatortype_append(OBJECT_OT_muscle_add);
 }
 
 void ED_operatormacros_object(void)
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index 73091e7..10f58ae 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -743,7 +743,7 @@ const char *buttons_context_dir[] = {
 	"texture", "texture_user", "texture_user_property", "bone", "edit_bone",
 	"pose_bone", "particle_system", "particle_system_editable", "particle_settings",
 	"cloth", "soft_body", "fluid", "smoke", "collision", "brush", "dynamic_paint",
-	"line_style", NULL
+	"line_style", "muscle", NULL
 };
 
 int buttons_context(const bContext *C, const char *member, bContextDataResult *result)
@@ -1063,6 +1063,10 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
 		set_pointer_type(path, result, &RNA_FreestyleLineStyle);
 		return 1;
 	}
+	else if (CTX_data_equals(member, "muscle")) {
+		set_pointer_type(path, result, &RNA_Muscle);
+		return 1;
+	}
 	else {
 		return 0; /* not found */
 	}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index ecedf35..d8c7228 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -7426,6 +7426,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
 					}
 				}
 				break;
+			case OB_MUSCLE:
+				if (!render_override) {
+					RegionView3D *rv3d = ar->regiondata;
+					draw_empty_sphere(rv3d->dist/50);
+				}
+				break;
 			default:
 				if (!render_override) {
 					drawaxes(1.0, OB_ARROWS);
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 33d1445..8fd3ab0 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -212,6 +212,8 @@ typedef struct PreviewImage {
 #define ID_PAL		MAKE_ID2('P', 'L') /* Palette */
 #define ID_PC		MAKE_ID2('P', 'C') /* PaintCurve  */
 
+#define ID_MU       MAKE_ID2('M', 'U') /* Muscle */
+
 	/* NOTE! Fake IDs, needed for g.sipo->blocktype or outliner */
 #define ID_SEQ		MAKE_ID2('S', 'Q')
 			/* constraint */
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 47782bb..cc7a0b9 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -82,6 +82,8 @@ typedef enum ModifierType {
 	eModifierType_MeshCache         = 46,
 	eModifierType_LaplacianDeform   = 47,
 	eModifierType_Wireframe         = 48,
+	eModifierType_Muscle            = 49,
+	eModifierType_MassSpring        = 50,
 	NUM_MODIFIER_TYPES
 } ModifierType;
 
@@ -1357,6 +1359,21 @@ typedef struct WireframeModifierData {
 	short pad[2];
 } WireframeModifierData;
 
+typedef struct MuscleModifierData {
+	ModifierData modifier;
+	char defgrp_name[64];    /* Name of vertex group to modify/weight. MAX_VGROUP_NAME. */
+	struct Object *muscle;    /* Associated muscle */
+	float contraction;
+	char pad[4];
+} MuscleModifierData;
+
+typedef struct MassSpringModifierData {
+	ModifierData modifier;
+	float factor;
+	char defgrp_name[64];    /* Name of vertex group to modify/weight. MAX_VGROUP_NAME. */
+	char pad[4];
+} MassSpringModifierData;
+
 enum {
 	MOD_WIREFRAME_INVERT_VGROUP = (1 << 0),
 	MOD_WIREFRAME_REPLACE       = (1 << 1),
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 0bcc6bf..ed3c692 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -354,6 +354,8 @@ enum {
 
 /* 23 and 24 are for life and sector (old file compat.) */
 	OB_ARMATURE   = 25,
+
+	OB_MUSCLE     = 26,
 };
 
 /* check if the object type supports materials */
@@ -368,10 +370,10 @@ enum {
 
 /* is this ID type used as object data */
 #define OB_DATA_SUPPORT_ID(_id_type) \
-	(ELEM(_id_type, ID_ME, ID_CU, ID_MB, ID_LA, ID_SPK, ID_CA, ID_LT, ID_AR))
+	(ELEM(_id_type, ID_ME, ID_CU, ID_MB, ID_LA, ID_SPK, ID_CA, ID_LT, ID_AR, ID_MU))
 
 #define OB_DATA_SUPPORT_ID_CASE \
-	ID_ME: case ID_CU: case ID_MB: case ID_LA: case ID_SPK: case ID_CA: case ID_LT: case ID_AR
+	ID_ME: case ID_CU: case ID_MB: case ID_LA: case ID_SPK: case ID_CA: case ID_LT: case ID_AR: case ID_MU
 
 /* partype: first 4 bits: type */
 enum {
@@ -679,6 +681,33 @@ typedef enum ObjectMode {
 
 #define MAX_DUPLI_RECUR 8
 
+typedef enum MuscleType {
+	MT_LINEAR = 0,
+	MT_SPHINCTER = 1,
+} MuscleType;
+
+/* MUSCLES */
+typedef struct Muscle {
+	ID id;
+	struct AnimData *adt;	/* animation data (must be immediately after id for utilities to use it) */ 
+
+	short type;
+
+	char pad[2];
+
+	float omega;
+	float Fs;
+	float Ff;
+	float K;
+	float wrinkle_h;
+	int wrinkle_n;
+
+	float R;
+	float H;
+
+	char pad2[4];
+} Muscle;
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index f0582b3..1ed6b74 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -398,6 +398,8 @@ extern StructRNA RNA_MovieTrackingObject;
 extern StructRNA RNA_MovieTrackingTrack;
 extern StructRNA RNA_MulticamSequence;
 extern StructRNA RNA_MultiresModifier;
+extern StructRNA RNA_Muscle;
+extern StructRNA RNA_MuscleModifier;
 extern StructRNA RNA_MusgraveTexture;
 extern StructRNA RNA_NandController;
 extern StructRNA RNA_NearSensor;
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 5d736f9..11fd781 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -64,6 +64,7 @@ set(DEFSRC
 	rna_meta.c
 	rna_modifier.c
 	rna_movieclip.c
+	rna_muscle.c
 	rna_nla.c
 	rna_nodetree.c
 	rna_object.c
@@ -111,6 +112,7 @@ set(APISRC
 	rna_material_api.c
 	rna_mesh_api.c
 	rna_meta_api.c
+	rna_muscle_api.c
 	rna_texture_api.c
 	rna_object_api.c
 	rna_pose_api.c
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 9b33e1f..f19d309 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -3297,6 +3297,7 @@ static RNAProcessItem PROCESS_ITEMS[] = {
 	{"rna_mesh.c", "rna_mesh_api.c", RNA_def_mesh},
 	{"rna_meta.c", "rna_meta_api.c", RNA_def_meta},
 	{"rna_modifier.c", NULL, RNA_def_modifier},
+	{"rna_muscle.c", "rna_muscle_api.c", RNA_def_muscle},
 	{"rna_nla.c", NULL, RNA_def_nla},
 	{"rna_nodetree.c", NULL, RNA_def_nodetree},
 	{"rna_object.c", "rna_object_api.c", RNA_def_object},
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 51d8129..1f9107d 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -64,6 +64,7 @@ EnumPropertyItem id_type_items[] = {
 	{ID_MA, "MATERIAL", ICON_MATERIAL_DATA, "Material", ""},
 	{ID_MB, "META", ICON_META_DATA, "MetaBall", ""},
 	{ID_ME, "MESH", ICON_MESH_DATA, "Mesh", ""},
+	{ID_MU, "MUSCLE", ICON_CAMERA_DATA, "Muscle", ""},
 	{ID_NT, "NODETREE", ICON_NODETREE, "NodeTree", ""},
 	{ID_OB, "OBJECT", ICON_OBJECT_DATA, "Object", ""},
 	{ID_PC, "PAINTCURVE", ICON_CURVE_BEZCURVE, "Paint Curve", ""},
@@ -158,6 +159,7 @@ short RNA_type_to_ID_code(StructRNA *type)
 	if (RNA_struct_is_a(type, &RNA_Mask)) return ID_MSK;
 	if (RNA_struct_is_a(type, &RNA_Palette)) return ID_PAL;
 	if (RNA_struct_is_a(type, &RNA_PaintCurve)) return ID_PC;
+	if (RNA_struct_is_a(type, &RNA_Muscle)) return ID_MU;
 
 	return 0;
 }
@@ -197,6 +199,7 @@ StructRNA *ID_code_to_RNA_type(short idcode)
 		case ID_MSK: return &RNA_Mask;
 		case ID_PAL: return &RNA_Palette;
 		case ID_PC: return &RNA_PaintCurve;
+		case ID_MU: return &RNA_Muscle;
 
 		default: return &RNA_ID;
 	}
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 051e727..dbc02f5 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -159,6 +159,7 @@ void RNA_def_material(struct BlenderRNA *brna);
 void RNA_def_mesh(struct BlenderRNA *brna);
 void RNA_def_meta(struct BlenderRNA *brna);
 void RNA_def_modifier(struct BlenderRNA *brna);
+void RNA_def_muscle(struct BlenderRNA *srna);
 void RNA_def_nla(struct BlenderRNA *brna);
 void RNA_def_nodetree(struct BlenderRNA *brna);
 void RNA_def_object(struct BlenderRNA *brna);
@@ -244,6 +245,7 @@ int rna_Curve_object_poll(struct PointerRNA *ptr, struct PointerRNA value);
 int rna_Lamp_object_poll(struct PointerRNA *ptr, struct PointerRNA value);
 int rna_Lattice_object_poll(struct PointerRNA *ptr, struct PointerRNA value);
 int rna_Mesh_object_poll(struct PointerRNA *ptr, struct PointerRNA value);
+int rna_Muscle_object_poll(struct PointerRNA *ptr, struct PointerRNA value);
 
 /* basic poll functions for actions (to prevent actions getting set in wrong places) */
 int rna_Action_id_poll(struct PointerRNA *ptr, struct PointerRNA value);
@@ -275,6 +277,7 @@ void RNA_api_main(struct StructRNA *srna);
 void RNA_api_material(StructRNA *srna);
 void RNA_api_mesh(struct StructRNA *srna);
 void RNA_api_meta(struct StructRNA *srna);
+void RNA_api_muscle(struct StructRNA *srna);
 void RNA_api_object(struct StructRNA *srna);
 void RNA_api_object_base(struct StructRNA *srna);
 void RNA_api_pose(struct StructRNA *srna);
@@ -326,6 +329,7 @@ void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop);
 void RNA_def_main_movieclips(BlenderRNA *brna, PropertyRNA *cprop);
 void RNA_def_main_masks(BlenderRNA *brna, PropertyRNA *cprop);
 void RNA_def_main_linestyles(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_muscles(BlenderRNA *brna, PropertyRNA *cprop);
 
 /* ID Properties */
 
diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c
index 65d8135..f7471ef 100644
--- a/source/blender/makesrna/intern/rna_main.c
+++ b/source/blender/makesrna/intern/rna_main.c
@@ -281,6 +281,12 @@ static void rna_Main_linestyle_begin(CollectionPropertyIterator *iter, PointerRN
 	rna_iterator_listbase_begin(iter, &bmain->linestyle, NULL);
 }
 
+static void rna_Main_muscle_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+	Main *bmain = (Main *)ptr->data;
+	rna_iterator_listbase_begin(iter, &bmain->muscles, NULL);
+}
+
 static void rna_Main_version_get(PointerRNA *ptr, int *value)
 {
 	Main *bmain = (Main *)ptr->data;
@@ -354,6 +360,7 @@ void RNA_def_main(BlenderRNA *brna)
 		{"movieclips", "MovieClip", "rna_Main_movieclips_begin", "Movie Clips", "Movie Clip datablocks", RNA_def_main_movieclips},
 		{"masks", "Mask", "rna_Main_masks_begin", "Masks", "Masks datablocks", RNA_def_main_masks},
 		{"linestyles", "FreestyleLineStyle", "rna_Main_linestyle_begin", "Line Styles", "Line Style datablocks", RNA_def_main_linestyles},
+		{"muscles", "Muscle", "rna_Main_muscle_begin", "Muscles", "Muscle datablocks", RNA_def_main_muscles},
 		{NULL, NULL, NULL, NULL, NULL, NULL}
 	};
 
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index b4c332b..379bc50 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -194,6 +194,9 @@ static Object *rna_Main_objects_new(Main *bmain, ReportList *reports, const char
 			case ID_AR:
 				type = OB_ARMATURE;
 				break;
+			case ID_MU:
+				type = OB_MUSCLE;
+				break;
 			default:
 			{
 				const char *idname;
@@ -701,6 +704,27 @@ static void rna_Main_linestyles_remove(Main *bmain, ReportList *reports, Freesty
 	/* XXX python now has invalid pointer? */
 }
 
+
+static Muscle *rna_Main_muscles_new(Main *bmain, const char *name)
+{
+	Muscle *me = BKE_muscle_add(bmain, name);
+	id_us_min(&me->id);
+	return me;
+}
+
+static void rna_Main_muscles_remove(Main *bmain, ReportList *reports, PointerRNA *mesh_ptr)
+{
+	Muscle *muscle = mesh_ptr->data;
+	if (ID_REAL_USERS(muscle) <= 0) {
+		BKE_libblock_free(bmain, muscle);
+		RNA_POINTER_INVALIDATE(mesh_ptr);
+	}
+	else {
+		BKE_reportf(reports, RPT_ERROR, "Mesh '%s' must have zero users to be removed, found %d",
+			muscle->id.name + 2, ID_REAL_USERS(muscle));
+	}
+}
+
 /* tag functions, all the same */
 static void rna_Main_cameras_tag(Main *bmain, int value) { BKE_main_id_tag_listbase(&bmain->camera, value); }
 static void rna_Main_scenes_tag(Main *bmain, int value) { BKE_main_id_tag_listbase(&bmain->scene, value); }
@@ -1812,5 +1836,37 @@ void RNA_def_main_linestyles(BlenderRNA *brna, PropertyRNA *cprop)
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 	RNA_def_property_boolean_funcs(prop, "rna_Main_linestyle_is_updated_get", NULL);
 }
+void RNA_def_main_muscles(BlenderRNA *brna, PropertyRNA *cprop)
+{
+	StructRNA *srna;
+	FunctionRNA *func;
+	PropertyRNA *parm;
+	PropertyRNA *prop;
+
+	static EnumPropertyItem mesh_type_items[] = {
+		{ eModifierMode_Realtime, "PREVIEW", 0, "Preview", "Apply modifier preview settings" },
+		{ eModifierMode_Render, "RENDER", 0, "Render", "Apply modifier render settings" },
+		{ 0, NULL, 0, NULL, NULL }
+	};
+
+	RNA_def_property_srna(cprop, "BlendDataMuscles");
+	srna = RNA_def_struct(brna, "BlendDataMuscles", NULL);
+	RNA_def_struct_sdna(srna, "Main");
+	RNA_def_struct_ui_text(srna, "Main Muscles", "Collection of muscles");
 
+	func = RNA_def_function(srna, "new", "rna_Main_muscles_new");
+	RNA_def_function_ui_description(func, "Add a new muscle to the main database");
+	parm = RNA_def_string(func, "name", "Muscle", 0, "", "New name for the datablock");
+	RNA_def_property_flag(parm, PROP_REQUIRED);
+	/* return type */
+	parm = RNA_def_pointer(func, "muscle", "Muscle", "", "New muscle datablock");
+	RNA_def_function_return(func, parm);
+
+	func = RNA_def_function(srna, "remove", "rna_Main_muscles_remove");
+	RNA_def_function_flag(func, FUNC_USE_REPORTS);
+	RNA_def_function_ui_description(func, "Remove a muscle from the current blendfile");
+	parm = RNA_def_pointer(func, "muscle", "Muscle", "", "Muscle to remove");
+	RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
+	RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
+}
 #endif
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 4911c10..84f7e6a 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -91,6 +91,7 @@ EnumPropertyItem modifier_type_items[] = {
 	{eModifierType_LaplacianDeform, "LAPLACIANDEFORM", ICON_MOD_MESHDEFORM, "Laplacian Deform", ""},
 	{eModifierType_Lattice, "LATTICE", ICON_MOD_LATTICE, "Lattice", ""},
 	{eModifierType_MeshDeform, "MESH_DEFORM", ICON_MOD_MESHDEFORM, "Mesh Deform", ""},
+	{eModifierType_Muscle, "MUSCLE", ICON_MOD_ARMATURE, "Muscle", ""},
 	{eModifierType_Shrinkwrap, "SHRINKWRAP", ICON_MOD_SHRINKWRAP, "Shrinkwrap", ""},
 	{eModifierType_SimpleDeform, "SIMPLE_DEFORM", ICON_MOD_SIMPLEDEFORM, "Simple Deform", ""},
 	{eModifierType_Smooth, "SMOOTH", ICON_MOD_SMOOTH, "Smooth", ""},
@@ -102,6 +103,7 @@ EnumPropertyItem modifier_type_items[] = {
 	{eModifierType_DynamicPaint, "DYNAMIC_PAINT", ICON_MOD_DYNAMICPAINT, "Dynamic Paint", ""},
 	{eModifierType_Explode, "EXPLODE", ICON_MOD_EXPLODE, "Explode", ""},
 	{eModifierType_Fluidsim, "FLUID_SIMULATION", ICON_MOD_FLUIDSIM, "Fluid Simulation", ""},
+	{eModifierType_MassSpring, "MASSSPRING", ICON_MOD_ARMATURE, "MassSpring", ""},
 	{eModifierType_Ocean, "OCEAN", ICON_MOD_OCEAN, "Ocean", ""},
 	{eModifierType_ParticleInstance, "PARTICLE_INSTANCE", ICON_MOD_PARTICLES, "Particle Instance", ""},
 	{eModifierType_ParticleSystem, "PARTICLE_SYSTEM", ICON_MOD_PARTICLES, "Particle System", ""},
@@ -244,6 +246,10 @@ static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr)
 			return &RNA_LaplacianDeformModifier;
 		case eModifierType_Wireframe:
 			return &RNA_WireframeModifier;
+		case eModifierType_Muscle:
+			return &RNA_MuscleModifier;
+		case eModifierType_MassSpring:
+			return &RNA_MassSpringModifier;
 		/* Default */
 		case eModifierType_None:
 		case eModifierType_ShapeKey:
@@ -316,7 +322,9 @@ RNA_MOD_VGROUP_NAME_SET(LaplacianDeform, anchor_grp_name);
 RNA_MOD_VGROUP_NAME_SET(LaplacianSmooth, defgrp_name);
 RNA_MOD_VGROUP_NAME_SET(Lattice, name);
 RNA_MOD_VGROUP_NAME_SET(Mask, vgroup);
+RNA_MOD_VGROUP_NAME_SET(MassSpring, defgrp_name);
 RNA_MOD_VGROUP_NAME_SET(MeshDeform, defgrp_name);
+RNA_MOD_VGROUP_NAME_SET(Muscle, defgrp_name);
 RNA_MOD_VGROUP_NAME_SET(Shrinkwrap, vgroup_name);
 RNA_MOD_VGROUP_NAME_SET(SimpleDeform, vgroup_name);
 RNA_MOD_VGROUP_NAME_SET(Smooth, defgrp_name);
@@ -404,6 +412,7 @@ RNA_MOD_OBJECT_SET(Mask, ob_arm, OB_ARMATURE);
 RNA_MOD_OBJECT_SET(MeshDeform, object, OB_MESH);
 RNA_MOD_OBJECT_SET(Shrinkwrap, target, OB_MESH);
 RNA_MOD_OBJECT_SET(Shrinkwrap, auxTarget, OB_MESH);
+RNA_MOD_OBJECT_SET(Muscle, muscle, OB_MUSCLE);
 
 static void rna_HookModifier_object_set(PointerRNA *ptr, PointerRNA value)
 {
@@ -3550,6 +3559,58 @@ static void rna_def_modifier_meshcache(BlenderRNA *brna)
 	RNA_def_property_update(prop, 0, "rna_Modifier_update");
 }
 
+static void rna_def_modifier_mass_spring(BlenderRNA *brna)
+{
+	StructRNA *srna;
+	PropertyRNA *prop;
+
+	srna = RNA_def_struct(brna, "MassSpringModifier", "Modifier");
+	RNA_def_struct_ui_text(srna, "Mass spring Modifier", "It's a mass spring modifier");
+	RNA_def_struct_sdna(srna, "MassSpringModifierData");
+	RNA_def_struct_ui_icon(srna, ICON_MODIFIER);
+
+	prop = RNA_def_property(srna, "factor", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "factor");
+	RNA_def_property_range(prop, 1.0f, 1000000.0f);
+	RNA_def_property_ui_text(prop, "Factor", "Desired max edge length extension");
+	RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+	prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
+	RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
+	RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name");
+	RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MassSpringModifier_defgrp_name_set");
+	RNA_def_property_update(prop, 0, "rna_Modifier_update");
+}
+
+static void rna_def_modifier_muscle(BlenderRNA *brna)
+{
+	StructRNA *srna;
+	PropertyRNA *prop;
+
+	srna = RNA_def_struct(brna, "MuscleModifier", "Modifier");
+	RNA_def_struct_ui_text(srna, "Muscle Modifier", "It's a muscle modifier");
+	RNA_def_struct_sdna(srna, "MuscleModifierData");
+	RNA_def_struct_ui_icon(srna, ICON_MODIFIER);
+
+	prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
+	RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
+	RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name");
+	RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MuscleModifier_defgrp_name_set");
+	RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+	prop = RNA_def_property(srna, "muscle", PROP_POINTER, PROP_NONE);
+	RNA_def_property_ui_text(prop, "Muscle", "Muscle object to deform with");
+	RNA_def_property_pointer_funcs(prop, NULL, "rna_MuscleModifier_muscle_set", NULL, "rna_Muscle_object_poll");
+	RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
+	RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+
+	prop = RNA_def_property(srna, "contraction", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "contraction");
+	RNA_def_property_range(prop, 0.0f, 1.0f);
+	RNA_def_property_ui_text(prop, "Contraction", "Muscle contraction value");
+	RNA_def_property_update(prop, 0, "rna_Modifier_update");
+}
+
 static void rna_def_modifier_laplaciandeform(BlenderRNA *brna)
 {
 	StructRNA *srna;
@@ -3759,7 +3820,9 @@ void RNA_def_modifier(BlenderRNA *brna)
 	rna_def_modifier_mask(brna);
 	rna_def_modifier_simpledeform(brna);
 	rna_def_modifier_warp(brna);
+	rna_def_modifier_mass_spring(brna);
 	rna_def_modifier_multires(brna);
+	rna_def_modifier_muscle(brna);
 	rna_def_modifier_surface(brna);
 	rna_def_modifier_smoke(brna);
 	rna_def_modifier_solidify(brna);
diff --git a/source/blender/makesrna/intern/rna_muscle.c b/source/blender/makesrna/intern/rna_muscle.c
new file mode 100644
index 0000000..d2122b3
--- /dev/null
+++ b/source/blender/makesrna/intern/rna_muscle.c
@@ -0,0 +1,109 @@
+/*
+ * ***** BEGIN GPL 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.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Blender Foundation (2008).
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/makesrna/intern/rna_muscle.c
+ *  \ingroup RNA
+ */
+
+#include <stdlib.h>
+
+#include "BLI_math.h"
+
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
+#include "WM_types.h"
+
+
+#include "DNA_object_types.h"
+
+EnumPropertyItem muscle_type_items[] = {
+	{ MT_LINEAR, "LINEAR", 0, "Linear", "" },
+	{ MT_SPHINCTER, "SPHINCTER", 0, "Sphincter", "" },
+	{ 0, NULL, 0, NULL, NULL }
+};
+
+#ifdef RNA_RUNTIME
+
+#else
+
+void RNA_def_muscle(BlenderRNA *brna)
+{
+	StructRNA *srna;
+	PropertyRNA *prop;
+
+	srna = RNA_def_struct(brna, "Muscle", "ID");
+	RNA_def_struct_ui_text(srna, "Muscle", "Muscle datablock for storing muscle settings");
+	RNA_def_struct_ui_icon(srna, ICON_CAMERA_DATA);
+
+	prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "type");
+	RNA_def_property_ui_text(prop, "Type", "Type of muscle");
+	RNA_def_property_enum_items(prop, muscle_type_items);
+	RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+
+	prop = RNA_def_property(srna, "omega", PROP_FLOAT, PROP_ANGLE);
+	RNA_def_property_float_sdna(prop, NULL, "omega");
+	RNA_def_property_ui_text(prop, "Omega", "Zone of influence");
+	RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+
+	prop = RNA_def_property(srna, "fs", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "Fs");
+	RNA_def_property_ui_text(prop, "Fallstart", "Fallstart value");
+	RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+
+	prop = RNA_def_property(srna, "ff", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "Ff");
+	RNA_def_property_ui_text(prop, "Fallfin", "Fallfin value");
+	RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+
+	prop = RNA_def_property(srna, "k", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "K");
+	RNA_def_property_ui_text(prop, "K", "Muscle spring constant");
+	RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+
+	prop = RNA_def_property(srna, "wrinkle_n", PROP_INT, PROP_NONE);
+	RNA_def_property_int_sdna(prop, NULL, "wrinkle_n");
+	RNA_def_property_ui_text(prop, "Wrinkle N", "Wrinkle count");
+	RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+
+	prop = RNA_def_property(srna, "wrinkle_h", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "wrinkle_h");
+	RNA_def_property_ui_text(prop, "Wrinkle H", "Height of wrinkle");
+	RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+
+	prop = RNA_def_property(srna, "r", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "R");
+	RNA_def_property_ui_text(prop, "R", "Sphincter muscle dest. radius");
+	RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+
+	prop = RNA_def_property(srna, "h", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "H");
+	RNA_def_property_ui_text(prop, "H", "Sphincter muscle height");
+	RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+
+	/* Camera API */
+	RNA_api_muscle(srna);
+}
+
+#endif
diff --git a/source/blender/makesrna/intern/rna_muscle_api.c b/source/blender/makesrna/intern/rna_muscle_api.c
new file mode 100644
index 0000000..acc3048
--- /dev/null
+++ b/source/blender/makesrna/intern/rna_muscle_api.c
@@ -0,0 +1,45 @@
+/*
+ * ***** BEGIN GPL 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.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/makesrna/intern/rna_muscle_api.c
+ *  \ingroup RNA
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "RNA_define.h"
+
+#include "rna_internal.h"  /* own include */
+
+#ifdef RNA_RUNTIME
+#else
+
+void RNA_api_muscle(StructRNA *srna)
+{
+
+}
+
+#endif
+
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 690468a..2a8560b 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -146,6 +146,7 @@ EnumPropertyItem object_type_items[] = {
 	{OB_CAMERA, "CAMERA", 0, "Camera", ""},
 	{OB_LAMP, "LAMP", 0, "Lamp", ""},
 	{OB_SPEAKER, "SPEAKER", 0, "Speaker", ""},
+	{OB_MUSCLE, "MUSCLE", 0, "Muscle", ""},
 	{0, NULL, 0, NULL, NULL}
 };
 
@@ -429,6 +430,7 @@ static StructRNA *rna_Object_data_typef(PointerRNA *ptr)
 		case OB_LATTICE: return &RNA_Lattice;
 		case OB_ARMATURE: return &RNA_Armature;
 		case OB_SPEAKER: return &RNA_Speaker;
+		case OB_MUSCLE: return &RNA_Muscle;
 		default: return &RNA_ID;
 	}
 }
@@ -1488,6 +1490,11 @@ int rna_Lamp_object_poll(PointerRNA *UNUSED(ptr), PointerRNA value)
 	return ((Object *)value.id.data)->type == OB_LAMP;
 }
 
+int rna_Muscle_object_poll(PointerRNA *UNUSED(ptr), PointerRNA value)
+{
+	return ((Object *)value.id.data)->type == OB_MUSCLE;
+}
+
 int rna_DupliObject_index_get(PointerRNA *ptr)
 {
 	DupliObject *dob = (DupliObject *)ptr->data;
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index 06e9f8f..53f2c32 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -64,6 +64,7 @@ set(SRC
 	intern/MOD_laplaciansmooth.c
 	intern/MOD_lattice.c
 	intern/MOD_mask.c
+	intern/MOD_mass_spring.c
 	intern/MOD_meshcache.c
 	intern/MOD_meshcache_mdd.c
 	intern/MOD_meshcache_pc2.c
@@ -71,6 +72,7 @@ set(SRC
 	intern/MOD_meshdeform.c
 	intern/MOD_mirror.c
 	intern/MOD_multires.c
+	intern/MOD_muscle.c
 	intern/MOD_none.c
 	intern/MOD_ocean.c
 	intern/MOD_particleinstance.c
diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h
index 9c7c21c..28ffde2 100644
--- a/source/blender/modifiers/MOD_modifiertypes.h
+++ b/source/blender/modifiers/MOD_modifiertypes.h
@@ -81,6 +81,8 @@ extern ModifierTypeInfo modifierType_UVWarp;
 extern ModifierTypeInfo modifierType_MeshCache;
 extern ModifierTypeInfo modifierType_LaplacianDeform;
 extern ModifierTypeInfo modifierType_Wireframe;
+extern ModifierTypeInfo modifierType_Muscle;
+extern ModifierTypeInfo modifierType_MassSpring;
 
 /* MOD_util.c */
 void modifier_type_init(ModifierTypeInfo *types[]);
diff --git a/source/blender/modifiers/intern/MOD_mass_spring.c b/source/blender/modifiers/intern/MOD_mass_spring.c
new file mode 100644
index 0000000..a401e7c
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_mass_spring.c
@@ -0,0 +1,165 @@
+/*
+* ***** BEGIN GPL 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.
+*
+* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The Original Code is Copyright (C) 2014 by the Blender Foundation.
+* All rights reserved.
+*
+* Contributor(s): Andrey Mramornov
+*
+* ***** END GPL LICENSE BLOCK *****
+*
+*/
+
+/** \file blender/modifiers/intern/MOD_mass_spring.c
+*  \ingroup modifiers
+*/
+
+#include <stdio.h>
+
+#include "DNA_scene_types.h"
+
+#include "BLI_utildefines.h"
+
+#include "BKE_cdderivedmesh.h"
+#include "BKE_particle.h"
+
+#include "MOD_modifiertypes.h"
+#include "MOD_util.h"
+#include "BKE_deform.h"
+#include "BLI_math.h"
+#include "DNA_mesh_types.h"
+
+static void deformVerts(ModifierData *md, Object *ob,
+	DerivedMesh *derivedData,
+	float(*vertexCos)[3],
+	int numVerts,
+	ModifierApplyFlag UNUSED(flag))
+{
+	int i;
+	MassSpringModifierData *mmd = (MassSpringModifierData*)md;
+
+	DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, false, false);
+
+	modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
+
+
+	Mesh *mesh = (Mesh*)ob->data;
+	const int numEdges = mesh->totedge;
+
+	float *v1, *v2, *v1o, *v2o, len, leno, factor;
+	float v1v2[3];
+	unsigned char *modified = malloc(numEdges*sizeof(char));
+	memset(modified, 0, numEdges*sizeof(char));
+	/*for (i = 0; i < numEdges; ++i) {
+		if ((len_v3v3(vertexCos[mesh->medge[i].v1], mesh->mvert[mesh->medge[i].v1].co) > 0.01) &&
+			(len_v3v3(vertexCos[mesh->medge[i].v1], mesh->mvert[mesh->medge[i].v1].co) > 0.01)) {
+			modified[i] = true;
+		}
+	}*/
+	bool change = false;
+	const unsigned char steps = 3;
+	int def_nr = defgroup_name_index(ob, mmd->defgrp_name);
+	do {
+		change = false;
+		for (i = 0; i < numEdges; ++i) {
+			if (modified[i] >= steps) {
+				continue;
+			}
+
+			if (def_nr != -1) {
+				if ((defvert_find_weight(dm->getVertData(dm, mesh->medge[i].v1, CD_MDEFORMVERT), def_nr) == 0.0f) ||
+					(defvert_find_weight(dm->getVertData(dm, mesh->medge[i].v2, CD_MDEFORMVERT), def_nr) == 0.0f))
+					continue;
+			}
+			v1 = vertexCos[mesh->medge[i].v1];
+			v2 = vertexCos[mesh->medge[i].v2];
+			sub_v3_v3v3(v1v2, v1, v2);
+			v1o = mesh->mvert[mesh->medge[i].v1].co;
+			v2o = mesh->mvert[mesh->medge[i].v2].co;
+			len = len_v3v3(v1, v2);
+			leno = len_v3v3(v1o, v2o);
+			factor = len / leno;
+			//too large
+			if (factor > mmd->factor) {
+				float step = (mmd->factor - 0.001) / factor;
+				//move vertex that is closer to it's original position
+				if (len_v3v3(v1, v1o) < len_v3v3(v2, v2o)) {
+					madd_v3_v3fl(v1, v1v2, -(1 - step)/(steps - modified[i]));
+				} else {
+					madd_v3_v3fl(v2, v1v2, (1 - step)/(steps - modified[i]));
+				}
+				modified[i]++;
+				change = true;
+				//that is slow and stupid
+				//break;
+			} 
+			//too small
+			/*else if (factor < (2 - mmd->factor)) {
+				float step = (2 - mmd->factor - 0.001) / factor;
+				//move vertex that is closer to it's original position
+				if (len_v3v3(v1, v1o) < len_v3v3(v2, v2o)) {
+					madd_v3_v3fl(v1, v1v2, (step - 1) / (steps - modified[i]));
+				}
+				else {
+					madd_v3_v3fl(v2, v1v2, -(step - 1) / (steps - modified[i]));
+				}
+				modified[i]++;
+				change = true;
+			}*/
+		}
+	} while (change);
+	free(modified);
+
+	if (dm && dm != derivedData)
+		dm->release(dm);
+
+	//printf("Hallo");
+	//sbObjectStep(md->scene, ob, (float)md->scene->r.cfra, vertexCos, numVerts);
+}
+
+static bool dependsOnTime(ModifierData *UNUSED(md))
+{
+	return true;
+}
+
+
+ModifierTypeInfo modifierType_MassSpring = {
+	/* name */              "MassSpring",
+	/* structName */        "MassSpringModifierData",
+	/* structSize */        sizeof(MassSpringModifierData),
+	/* type */              eModifierTypeType_OnlyDeform,
+	/* flags */             eModifierTypeFlag_AcceptsMesh |
+                            eModifierTypeFlag_RequiresOriginalData,
+
+	/* copyData */          NULL,
+	/* deformVerts */       deformVerts,
+	/* deformMatrices */    NULL,
+	/* deformVertsEM */     NULL,
+	/* deformMatricesEM */  NULL,
+	/* applyModifier */     NULL,
+	/* applyModifierEM */   NULL,
+	/* initData */          NULL,
+	/* requiredDataMask */  NULL,
+	/* freeData */          NULL,
+	/* isDisabled */        NULL,
+	/* updateDepgraph */    NULL,
+	/* dependsOnTime */     NULL,
+	/* dependsOnNormals */	NULL,
+	/* foreachObjectLink */ NULL,
+	/* foreachIDLink */     NULL,
+	/* foreachTexLink */    NULL,
+};
diff --git a/source/blender/modifiers/intern/MOD_muscle.c b/source/blender/modifiers/intern/MOD_muscle.c
new file mode 100644
index 0000000..96826f9
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_muscle.c
@@ -0,0 +1,305 @@
+/*
+ * ***** BEGIN GPL 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.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Daniel Dunbar
+ *                 Ton Roosendaal,
+ *                 Ben Batt,
+ *                 Brecht Van Lommel,
+ *                 Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ */
+
+/** \file blender/modifiers/intern/MOD_softbody.c
+ *  \ingroup modifiers
+ */
+
+#include <stdio.h>
+
+#include "DNA_scene_types.h"
+
+#include "BLI_utildefines.h"
+
+#include "BKE_cdderivedmesh.h"
+#include "BKE_particle.h"
+
+#include "MOD_modifiertypes.h"
+#include "MOD_util.h"
+#include "BKE_deform.h"
+#include "BLI_math.h"
+#include "BLI_linklist.h"
+
+static void deformVertsLinear(ModifierData *md, Object *ob,
+                        DerivedMesh *derivedData,
+                        float (*vertexCos)[3],
+                        int numVerts,
+                        ModifierApplyFlag UNUSED(flag))
+{
+	int i;
+	MuscleModifierData *mmd = (MuscleModifierData*)md;
+	if (!mmd->muscle || (mmd->muscle->type != OB_MUSCLE)) {
+		//smth wrong
+		return;
+	}
+	Object *muscle = mmd->muscle;
+	Object *muscle2 = muscle->parent;
+	Muscle *muscle_data = (Muscle*)muscle->data;
+	if (!muscle2) {
+		return;
+	}
+	float d[3], v1_v2[3], v1[3], v2[3], pd[3];
+	float* p;
+	copy_v3_v3(v1, muscle->loc);
+	copy_v3_v3(v2, muscle2->loc);
+	//relative coords
+	add_v3_v3(v1, v2);
+	copy_v3_v3(v1_v2, v2);
+	sub_v3_v3(v1_v2, v1);
+	float a, r, mu;
+	float D;
+	float sz = len_v3(v1_v2);
+	float Ff = muscle_data->Ff*sz;
+	float Fs = muscle_data->Fs*sz;
+	float pc[3];
+	float wrinkleL = Ff * cos(muscle_data->omega/2) - Fs;
+	const int wrinkleN = muscle_data->wrinkle_n;
+	float wrinkleB = wrinkleL / (2.0f*wrinkleN);
+	float wrinkleH = muscle_data->wrinkle_h;
+	float obinv[4][4];
+	invert_m4_m4(obinv, ob->obmat);
+	
+	DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, false, false);
+
+	modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
+
+	int def_nr = defgroup_name_index(ob, mmd->defgrp_name);
+
+	for (i = 0; i < numVerts; i++) {
+		float weight = 1.0f; /* default to 1 if no overall def group */
+
+		if (def_nr != -1) {
+			weight = defvert_find_weight(dm->getVertData(dm, i, CD_MDEFORMVERT), def_nr);
+		}
+
+		/* check if there's any  point in calculating for this vert */
+		if (weight == 0.0f)
+			continue;
+
+		weight *= mmd->contraction;
+		
+		p = vertexCos[i];
+		mul_m4_v3(ob->obmat, p);
+		sub_v3_v3v3(pc, p, v1);
+		mu = angle_v3v3(pc, v1_v2);
+		a = cos(mu);
+		sub_v3_v3v3(d, p, v1);
+		D = len_v3(d);
+		//if it's in bounds
+		if ((mu < muscle_data->omega / 2) && (D < Ff)) {
+			//muscle
+			if (D > Fs) {
+				r = cos((D - Fs) / (Ff - Fs) * M_PI_2);
+			}
+			else {
+				r = cos((1 - D/Fs) * M_PI_2);
+			}
+			normalize_v3(d);
+			p[0] -= D*weight*muscle_data->K*a*r*d[0];
+			p[1] -= D*weight*muscle_data->K*a*r*d[1];
+			p[2] -= D*weight*muscle_data->K*a*r*d[2];
+
+			//wrinkle
+			if (wrinkleN > 0) {
+				float axisD = D * cos(mu) - Fs;
+				if ((axisD < wrinkleL) && (axisD > 0.0)) {
+					float u = axisD - floor(axisD / wrinkleB / 2.0) * wrinkleB * 2.0;
+					float wrinkleAmplitude = wrinkleH * weight * (1 - (u - wrinkleB)*(u - wrinkleB) / (wrinkleB*wrinkleB));
+					float norm[3];
+					dm->getVertNo(dm, i, norm);
+					madd_v3_v3fl(p, norm, wrinkleAmplitude);
+				}
+			}
+		}
+		mul_m4_v3(obinv, p);
+	}
+
+
+	if (dm && dm != derivedData)
+		dm->release(dm);
+}
+
+static LinkNode *getChildren(Scene* sc, Object* ob)
+{
+	LinkNode* result = NULL;
+	Base *base;
+
+	/* Remove markers from all objects */
+	for (base = sc->base.first; base; base = base->next) {
+		if (base->object->parent == ob) {
+			BLI_linklist_append(&result, base->object);
+		}
+	}
+	return result;
+}
+
+static void deformVertsSphincter(ModifierData *md, Object *ob,
+	DerivedMesh *derivedData,
+	float(*vertexCos)[3],
+	int numVerts,
+	ModifierApplyFlag flag)
+{
+	int i;
+	MuscleModifierData *mmd = (MuscleModifierData*)md;
+	Object *muscle = mmd->muscle;
+	Muscle *muscle_data = (Muscle*)muscle->data;
+
+	float* p;
+	float v1[3], pv1[3], norm[3], cp1[3], cp2[3], normcp1[3], normcp2[3];
+	float v1cp1[3], v1cp2[3];
+	copy_v3_v3(v1, muscle->loc);
+	float obinv[4][4];
+	invert_m4_m4(obinv, ob->obmat);
+
+	LinkNode* children = getChildren(md->scene, muscle);
+	if (BLI_linklist_length(children) != 2) {
+		BLI_linklist_free(children, NULL);
+		return;
+	}
+	add_v3_v3v3(cp1, ((Object*)children->link)->loc, v1);
+	children = children->next;
+	add_v3_v3v3(cp2, ((Object*)children->link)->loc, v1);
+	BLI_linklist_free(children, NULL);
+
+	DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, false, false);
+
+	modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
+
+	int def_nr = defgroup_name_index(ob, mmd->defgrp_name);
+
+	sub_v3_v3v3(v1cp1, cp1, v1);
+	sub_v3_v3v3(v1cp2, cp2, v1);
+	normalize_v3_v3(normcp1, v1cp1);
+	normalize_v3_v3(normcp2, v1cp2);
+	float l1 = len_v3(v1cp1);
+	float l2 = len_v3(v1cp2);
+	float plane_norm[3];
+	float projected[3], tmp[3];
+	cross_v3_v3v3(plane_norm, v1cp1, v1cp2);
+	normalize_v3(plane_norm);
+	float cr1 = l1 - mmd->contraction * (l1 - muscle_data->R);
+	float cr2 = l2 - mmd->contraction * (l2 - muscle_data->R);
+
+	for (i = 0; i < numVerts; i++) {
+		float weight = 1.0f; /* default to 1 if no overall def group */
+
+		if (def_nr != -1) {
+			weight = defvert_find_weight(dm->getVertData(dm, i, CD_MDEFORMVERT), def_nr);
+		}
+
+		/* check if there's any  point in calculating for this vert */
+		if (weight == 0.0f)
+			continue;
+
+		weight *= mmd->contraction;
+
+		p = vertexCos[i];
+		mul_m4_v3(ob->obmat, p);
+
+		sub_v3_v3v3(pv1, v1, p);
+		copy_v3_v3(projected, pv1);
+		madd_v3_v3fl(projected, plane_norm, -dot_v3v3(pv1, plane_norm));
+		float D = len_v3(projected);
+		float mu = angle_v3v3(projected, v1cp1);
+		float d1 = (cos(mu)*D);
+		mu = angle_v3v3(projected, v1cp2);
+		float d2 = (cos(mu)*D);
+		//if it's in bounds
+		if ((fabs(d1) < l1) && (fabs(d2) < l2)) {
+			normalize_v3(pv1);
+			dm->getVertNo(dm, i, norm);
+			//todo: settings!
+			norm[0] = 0.0f;
+			norm[1] = -1.0f;
+			norm[2] = 0.0f;
+			madd_v3_v3fl(p, normcp1, weight*d1*(1 - muscle_data->R / l1));
+			madd_v3_v3fl(p, normcp2, weight*d2*(1 - muscle_data->R / l2));
+			madd_v3_v3fl(p, norm, weight*muscle_data->H*min(muscle_data->R/max(l1,l2), (1 - D*D / (muscle_data->Ff * muscle_data->Ff))));
+		}
+		mul_m4_v3(obinv, p);
+	}
+
+	if (dm && dm != derivedData)
+		dm->release(dm);
+}
+
+
+static void deformVerts(ModifierData *md, Object *ob,
+	DerivedMesh *derivedData,
+	float(*vertexCos)[3],
+	int numVerts,
+	ModifierApplyFlag flag)
+{
+	MuscleModifierData *mmd = (MuscleModifierData*)md;
+	if (!mmd->muscle || (mmd->muscle->type != OB_MUSCLE)) {
+		//smth wrong
+		return;
+	}
+	Object *muscle = mmd->muscle;
+	Muscle *muscle_data = (Muscle*)muscle->data;
+	if (muscle_data->type == MT_LINEAR) {
+		deformVertsLinear(md, ob, derivedData, vertexCos, numVerts, flag);
+	}
+	else {
+		deformVertsSphincter(md, ob, derivedData, vertexCos, numVerts, flag);
+	}
+}
+
+static bool dependsOnTime(ModifierData *UNUSED(md))
+{
+	return true;
+}
+
+
+ModifierTypeInfo modifierType_Muscle = {
+	/* name */              "Muscle",
+	/* structName */        "MuscleModifierData",
+	/* structSize */        sizeof(MuscleModifierData),
+	/* type */              eModifierTypeType_OnlyDeform,
+	/* flags */             eModifierTypeFlag_AcceptsMesh,
+
+	/* copyData */          NULL,
+	/* deformVerts */       deformVerts,
+	/* deformMatrices */    NULL,
+	/* deformVertsEM */     NULL,
+	/* deformMatricesEM */  NULL,
+	/* applyModifier */     NULL,
+	/* applyModifierEM */   NULL,
+	/* initData */          NULL,
+	/* requiredDataMask */  NULL,
+	/* freeData */          NULL,
+	/* isDisabled */        NULL,
+	/* updateDepgraph */    NULL,
+	/* dependsOnTime */     NULL,
+	/* dependsOnNormals */	NULL,
+	/* foreachObjectLink */ NULL,
+	/* foreachIDLink */     NULL,
+	/* foreachTexLink */    NULL,
+};
diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c
index 829c2b8..aeea60f 100644
--- a/source/blender/modifiers/intern/MOD_util.c
+++ b/source/blender/modifiers/intern/MOD_util.c
@@ -309,5 +309,7 @@ void modifier_type_init(ModifierTypeInfo *types[])
 	INIT_TYPE(MeshCache);
 	INIT_TYPE(LaplacianDeform);
 	INIT_TYPE(Wireframe);
+	INIT_TYPE(Muscle);
+	INIT_TYPE(MassSpring);
 #undef INIT_TYPE
 }
