Index: source/blender/blenlib/BLI_editVert.h
===================================================================
--- source/blender/blenlib/BLI_editVert.h	(revision 22920)
+++ source/blender/blenlib/BLI_editVert.h	(working copy)
@@ -64,8 +64,9 @@
 	
 	/* f stores selection eg. if (eve->f & SELECT) {...
 	h for hidden. if (!eve->h) {...
-	f1 and f2 can be used for temp data, clear them first*/
-	unsigned char f, h, f1, f2; 
+	f1 and f2 can be used for temp data, clear them first
+	p stores pinning*/
+	unsigned char f, h, f1, f2, p;
 	float bweight;
 	short fast;	/* only 0 or 1, for editmesh_fastmalloc, do not store temp data here! */
 	int hash;
Index: source/blender/include/BIF_editmesh.h
===================================================================
--- source/blender/include/BIF_editmesh.h	(revision 22920)
+++ source/blender/include/BIF_editmesh.h	(working copy)
@@ -146,6 +146,9 @@
 extern void selectconnected_delimit_mesh_all(void);
 extern void selectswap_mesh(void);
 
+extern void pin_mesh(int swap);
+extern void unpin_mesh(int swap);
+
 extern void hide_mesh(int swap);
 extern void reveal_mesh(void);
 
Index: source/blender/makesdna/DNA_meshdata_types.h
===================================================================
--- source/blender/makesdna/DNA_meshdata_types.h	(revision 22920)
+++ source/blender/makesdna/DNA_meshdata_types.h	(working copy)
@@ -180,6 +180,7 @@
 #define ME_SPHERETEST	2
 #define ME_SPHERETEMP	4
 #define ME_HIDE			16
+#define ME_PIN			32
 #define ME_VERT_MERGED		(1<<6)
 
 /* medge->flag (1=SELECT)*/
Index: source/blender/src/drawobject.c
===================================================================
--- source/blender/src/drawobject.c	(revision 22920)
+++ source/blender/src/drawobject.c	(working copy)
@@ -1382,6 +1382,14 @@
 	int sel = *((int*) userData);
 
 	if (efa->h==0 && efa->fgonf!=EM_FGON && (efa->f&SELECT)==sel) {
+		/* draw face centers red if pinned */
+		if (efa->v1->p && efa->v2->p && efa->v3->p && efa->v4->p) {
+			glColor3ub(200,0,0);
+		}
+		else {
+			glColor3ub(0,0,0);
+		}
+
 		bglVertex3fv(cent);
 	}
 }
@@ -1423,24 +1431,43 @@
 	EditVert *eve = EM_get_vert_for_index(index);
 
 	if (eve->h==0 && (eve->f&SELECT)==data->sel) {
-		/* draw active larger - need to stop/start point drawing for this :/ */
-		if (eve==data->eve_act) {
-			float size = BIF_GetThemeValuef(TH_VERTEX_SIZE);
-			BIF_ThemeColor4(TH_EDITMESH_ACTIVE);
-			
+	
+		/* draw pinned verts larger and in different color */
+		if (eve->p) {
+			glColor3ub(255,0,0);
 			bglEnd();
-			
-			glPointSize(size);
+			glPointSize(5);
 			bglBegin(GL_POINTS);
 			bglVertex3fv(co);
+		} else {
+			float size = BIF_GetThemeValuef(TH_VERTEX_SIZE);
 			bglEnd();
-			
 			BIF_ThemeColor4(data->sel?TH_VERTEX_SELECT:TH_VERTEX);
 			glPointSize(size);
 			bglBegin(GL_POINTS);
-		} else {
-			bglVertex3fv(co);
 		}
+
+		/* only draw verts if in vert select mode */
+		if (G.scene->selectmode & SCE_SELECT_VERTEX) {
+			/* draw active larger - need to stop/start point drawing for this :/ */
+			if (eve==data->eve_act) {
+				float size = BIF_GetThemeValuef(TH_VERTEX_SIZE);
+				BIF_ThemeColor4(TH_EDITMESH_ACTIVE);
+				
+				bglEnd();
+				
+				glPointSize(size);
+				bglBegin(GL_POINTS);
+				bglVertex3fv(co);
+				bglEnd();
+				
+				BIF_ThemeColor4(data->sel?TH_VERTEX_SELECT:TH_VERTEX);
+				glPointSize(size);
+				bglBegin(GL_POINTS);
+			} else {
+				bglVertex3fv(co);
+			}
+		}
 	}
 }
 static void draw_dm_verts(DerivedMesh *dm, int sel, EditVert *eve_act)
@@ -1476,6 +1503,11 @@
 			
 			glColor4ubv(col);
 		}
+
+		/* draw pinned edges in red */
+		if(G.scene->selectmode & SCE_SELECT_EDGE) {
+			if(eed->v1->p && eed->v2->p) glColor3ub(255,0,0);
+		}
 		return 1;
 	} else {
 		return 0;
@@ -1563,11 +1595,21 @@
 	if (efa->h==0) {
 		if (efa == data->efa_act) {
 			glColor4ubv(data->cols[2]);
+			
+			/* draw active face redish if it's pinned */
+			if(G.scene->selectmode & SCE_SELECT_FACE) {
+				if(efa->v1->p && efa->v2->p && efa->v3->p && efa->v4->p) glColor3ub(220,0,0);
+			}
 			return 2; /* stipple */
 		} else {
 			col = data->cols[(efa->f&SELECT)?1:0];
 			if (col[3]==0) return 0;
 			glColor4ubv(col);
+
+			/* draw pinned faces redish */
+			if(G.scene->selectmode & SCE_SELECT_FACE) {
+				if(efa->v1->p && efa->v2->p && efa->v3->p && efa->v4->p) glColor3ub(100,30,30);
+			}
 			return 1;
 		}
 	}
@@ -1681,11 +1723,11 @@
 				col[3] = fcol[3] = 255;
 			}
 				
-			if(G.scene->selectmode & SCE_SELECT_VERTEX) {
+			//if(G.scene->selectmode & SCE_SELECT_VERTEX) {
 				glPointSize(size);
 				glColor4ubv((GLubyte *)col);
 				draw_dm_verts(cageDM, sel, eve_act);
-			}
+			//}
 			
 			if( CHECK_OB_DRAWFACEDOT(G.scene, G.vd, G.obedit->dt) ) {
 				glPointSize(fsize);
Index: source/blender/src/editmesh.c
===================================================================
--- source/blender/src/editmesh.c	(revision 22920)
+++ source/blender/src/editmesh.c	(working copy)
@@ -953,6 +953,7 @@
 			eve->f |= (mvert->flag & 1);
 		
 		if (mvert->flag & ME_HIDE) eve->h= 1;		
+		if (mvert->flag & ME_PIN) eve->p = 1;
 		eve->no[0]= mvert->no[0]/32767.0;
 		eve->no[1]= mvert->no[1]/32767.0;
 		eve->no[2]= mvert->no[2]/32767.0;
@@ -1222,6 +1223,7 @@
 		if(eve->f1==1) mvert->flag |= ME_SPHERETEST;
 		mvert->flag |= (eve->f & SELECT);
 		if (eve->h) mvert->flag |= ME_HIDE;
+		if (eve->p) mvert->flag |= ME_PIN;
 		mvert->bweight= (char)(255.0*eve->bweight);
 
 #ifdef WITH_VERSE
@@ -1966,7 +1968,7 @@
 {
 	float no[3];
 	float co[3];
-	unsigned char f, h;
+	unsigned char f, h, p;
 	short bweight;
 	int keyindex;
 } EditVertC;
@@ -2074,6 +2076,7 @@
 
 		evec->f= eve->f;
 		evec->h= eve->h;
+		evec->p= eve->p;
 		evec->keyindex= eve->keyindex;
 		eve->tmp.l = a; /*store index*/
 		evec->bweight= (short)(eve->bweight*255.0);
@@ -2204,6 +2207,7 @@
 		VECCOPY(eve->no, evec->no);
 		eve->f= evec->f;
 		eve->h= evec->h;
+		eve->p= evec->p;
 		eve->keyindex= evec->keyindex;
 		eve->bweight= ((float)evec->bweight)/255.0f;
 
Index: source/blender/src/editmesh_mods.c
===================================================================
--- source/blender/src/editmesh_mods.c	(revision 22920)
+++ source/blender/src/editmesh_mods.c	(working copy)
@@ -2518,6 +2518,91 @@
 }	
 	
 	
+/* swap is 0 or 1, if 1 it pins not selected */
+void pin_mesh(int swap)
+{
+	EditMesh *em = G.editMesh;
+	EditVert *eve;
+	EditEdge *eed;
+	EditFace *efa;
+
+	if(G.obedit==0) return;
+
+	if(G.scene->selectmode & SCE_SELECT_VERTEX) {
+		for(eve= em->verts.first; eve; eve= eve->next) {
+			if((eve->f & SELECT)!=swap) {
+				eve->p = 1;
+			}
+		}
+	}
+	else if(G.scene->selectmode & SCE_SELECT_EDGE) {
+		for(eed= em->edges.first; eed; eed= eed->next) {
+			if((eed->f & SELECT)!=swap) {
+				eed->v1->p = 1;
+				eed->v2->p = 1;
+			}
+		}
+	}
+	else {
+		for(efa= em->faces.first; efa; efa= efa->next) {
+			if((efa->f & SELECT)!=swap) {
+				efa->v1->p = 1;
+				efa->v2->p = 1;
+				efa->v3->p = 1;
+				efa->v4->p = 1;
+			}
+		}
+	}
+
+	allqueue(REDRAWVIEW3D, 0);
+
+	BIF_undo_push("Pin");
+
+}
+
+/* swap is 0 or 1, if 1 it unpins not selected */
+void unpin_mesh(int swap)
+{
+	EditMesh *em = G.editMesh;
+	EditVert *eve;
+	EditEdge *eed;
+	EditFace *efa;
+
+	if(G.obedit==0) return;
+
+	if(G.scene->selectmode & SCE_SELECT_VERTEX) {
+		for(eve= em->verts.first; eve; eve= eve->next) {
+			if(eve->p && ((eve->f & SELECT)!=swap)) {
+				eve->p = 0;
+			}
+		}
+	}
+
+	else if(G.scene->selectmode & SCE_SELECT_EDGE) {
+		for(eed= em->edges.first; eed; eed= eed->next) {
+			if((eed->v1->p || eed->v2->p) && ((eed->f & SELECT)!=swap)) {
+				eed->v1->p = 0;
+				eed->v2->p = 0;
+			}
+		}
+	}
+	else {
+		for(efa= em->faces.first; efa; efa= efa->next) {
+			if((efa->v1->p || efa->v2->p || efa->v3->p || efa->v4->p) && ((efa->f & SELECT)!=swap)) {
+				efa->v1->p = 0;
+				efa->v2->p = 0;
+				efa->v3->p = 0;
+				efa->v4->p = 0;
+			}
+		}
+	}
+
+	allqueue(REDRAWVIEW3D, 0);
+
+	BIF_undo_push("Unpin");
+}
+
+
 /* swap is 0 or 1, if 1 it hides not selected */
 void hide_mesh(int swap)
 {
Index: source/blender/src/space.c
===================================================================
--- source/blender/src/space.c	(revision 22920)
+++ source/blender/src/space.c	(working copy)
@@ -2982,6 +2982,19 @@
 					}
 				}
 				break;
+			case RETKEY:
+				/* vertex pinning */
+				if (G.obedit->type==OB_MESH) {
+					if(G.qual==(LR_ALTKEY | LR_SHIFTKEY) || G.qual==(LR_ALTKEY | LR_CTRLKEY | LR_SHIFTKEY))
+						unpin_mesh(1);
+					else if(G.qual==LR_ALTKEY || G.qual==(LR_ALTKEY | LR_CTRLKEY))
+						unpin_mesh(0);
+					else if(G.qual==LR_SHIFTKEY)
+						pin_mesh(1);
+					else if(G.qual==0)
+						pin_mesh(0);
+				}
+				break;
 			}
 		}
 	}
Index: source/blender/src/transform_conversions.c
===================================================================
--- source/blender/src/transform_conversions.c	(revision 22920)
+++ source/blender/src/transform_conversions.c	(working copy)
@@ -2182,6 +2182,9 @@
 			if(propmode || eve->f1) {
 				VertsToTransData(tob, eve);
 				
+				/* pinned */
+				if (eve->p) tob->flag |= TD_SKIP;
+
 				/* selected */
 				if(eve->f1) tob->flag |= TD_SELECTED;
 				
