diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 8e08c6aa6cce2d53d3e1fabcfa3cf9ad822f2494..8d5b3c648ec56b0782a022ded65ab48442278bbc 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -291,7 +291,7 @@ BOOL LLFloaterModelPreview::postBuild()
 
 	childSetCommitCallback("lod_mode", onLODParamCommit, this);
 	childSetCommitCallback("lod_error_threshold", onLODParamCommit, this);
-	childSetCommitCallback("lod_triangle_limit", onLODParamCommit, this);
+	childSetCommitCallback("lod_triangle_limit", onLODParamCommitTriangleLimit, this);
 	childSetCommitCallback("build_operator", onLODParamCommit, this);
 	childSetCommitCallback("queue_mode", onLODParamCommit, this);
 	childSetCommitCallback("border_mode", onLODParamCommit, this);
@@ -533,9 +533,14 @@ void LLFloaterModelPreview::onAutoFillCommit(LLUICtrl* ctrl, void* userdata)
 void LLFloaterModelPreview::onLODParamCommit(LLUICtrl* ctrl, void* userdata)
 {
 	LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata;
-	fp->mModelPreview->genLODs(fp->mModelPreview->mPreviewLOD);
-	fp->mModelPreview->updateStatusMessages();
-	fp->mModelPreview->refresh();
+	fp->mModelPreview->onLODParamCommit(false);
+}
+
+//static
+void LLFloaterModelPreview::onLODParamCommitTriangleLimit(LLUICtrl* ctrl, void* userdata)
+{
+	LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata;
+	fp->mModelPreview->onLODParamCommit(true);
 }
 
 
@@ -2843,7 +2848,7 @@ bool LLModelPreview::containsRiggedAsset( void )
 	}
 	return false;
 }
-void LLModelPreview::genLODs(S32 which_lod, U32 decimation)
+void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_limit)
 {
 	if (mBaseModel.empty())
 	{
@@ -3074,7 +3079,17 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation)
 		}
 		else
 		{
-			triangle_count = limit;
+			if (enforce_tri_limit)
+			{
+				triangle_count = limit;
+			}
+			else
+			{
+				for (S32 j=LLModel::LOD_HIGH; j>which_lod; --j)
+				{
+					triangle_count /= decimation;
+				}
+			}
 		}
 
 		mModel[lod].clear();
@@ -4340,6 +4355,13 @@ void LLModelPreview::textureLoadedCallback( BOOL success, LLViewerFetchedTexture
 	preview->refresh();
 }
 
+void LLModelPreview::onLODParamCommit(bool enforce_tri_limit)
+{
+	genLODs(mPreviewLOD, 3, enforce_tri_limit);
+	updateStatusMessages();
+	refresh();
+}
+
 LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LLModel* mdl)
 {
 	mStage = stage;
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index fbf6ead930ffdfdfbbb9e68785db1b8e141bcceb..9ea1b5131a4541f2aa5d3e0340fe5f4960cc6476 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -189,6 +189,7 @@ class LLFloaterModelPreview : public LLFloater
 	
 	static void		onAutoFillCommit(LLUICtrl*,void*);
 	static void		onLODParamCommit(LLUICtrl*,void*);
+	static void		onLODParamCommitTriangleLimit(LLUICtrl*,void*);
 	
 	static void		onExplodeCommit(LLUICtrl*, void*);
 	
@@ -234,6 +235,7 @@ class LLFloaterModelPreview : public LLFloater
 	LLMenuButton* mViewOptionMenuButton;
 	LLToggleableMenu* mViewOptionMenu;
 	LLMutex* mStatusLock;
+
 };
 
 class LLMeshFilePicker : public LLFilePickerThread
@@ -254,7 +256,7 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
 	typedef boost::signals2::signal<void (void)> model_loaded_signal_t;
 
 public:
-	 LLModelPreview(S32 width, S32 height, LLFloater* fmp);
+	LLModelPreview(S32 width, S32 height, LLFloater* fmp);
 	virtual ~LLModelPreview();
 
 	void resetPreviewTarget();
@@ -275,7 +277,7 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
 	void clearModel(S32 lod);
 	void loadModel(std::string filename, S32 lod);
 	void loadModelCallback(S32 lod);
-	void genLODs(S32 which_lod = -1, U32 decimation = 3);
+	void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false);
 	void generateNormals();
 	void consolidate();
 	void clearMaterials();
@@ -285,6 +287,7 @@ class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
 	void updateStatusMessages();
 	bool containsRiggedAsset( void );
 	void clearGLODGroup();
+	void onLODParamCommit(bool enforce_tri_limit);
 
 	static void	textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );
 	
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index ded3e36cf62c5bd38c6a0d444a78c98a7999281d..b667dc1af0b551c65de722f4c391538cea50bad1 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -2895,10 +2895,8 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
 				}
 				
 	LLVector3 name_position = idleUpdateNameTagPosition(root_pos_last);
-	mNameText->setPositionAgent(name_position);
-				
-	idleUpdateNameTagText(new_name);
-			
+	mNameText->setPositionAgent(name_position);				
+	idleUpdateNameTagText(new_name);			
 	idleUpdateNameTagAlpha(new_name, alpha);
 }
 
@@ -3184,8 +3182,9 @@ void LLVOAvatar::invalidateNameTags()
 		if (avatar->isDead()) continue;
 
 		avatar->clearNameTag();
-				}
-			}
+
+	}
+}
 
 // Compute name tag position during idle update
 LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
@@ -3204,12 +3203,14 @@ LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
 	local_camera_up.scaleVec(mBodySize * 0.5f);
 	local_camera_at.scaleVec(mBodySize * 0.5f);
 
-	LLVector3 name_position = mRoot.getWorldPosition() + 
-		(local_camera_up * root_rot) -
-		(projected_vec(local_camera_at * root_rot, camera_to_av));
+	LLVector3 name_position = mRoot.getWorldPosition();
+	name_position[VZ] -= mPelvisToFoot;
+	name_position[VZ] += (mBodySize[VZ]* 0.55f);
+	name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av));	
 	name_position += pixel_up_vec * 15.f;
+
 	return name_position;
-		}
+}
 
 void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha)
 {
@@ -6026,6 +6027,34 @@ void LLVOAvatar::rebuildRiggedAttachments( void )
 	}
 }
 //-----------------------------------------------------------------------------
+// cleanupAttachedMesh()
+//-----------------------------------------------------------------------------
+void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
+{
+	//If a VO has a skin that we'll reset the joint positions to their default
+	if ( pVO && pVO->mDrawable )
+	{
+		LLVOVolume* pVObj = pVO->mDrawable->getVOVolume();
+		if ( pVObj )
+		{
+			const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID() );
+			if ( pSkinData )
+			{
+				const int jointCnt = pSkinData->mJointNames.size();
+				bool fullRig = ( jointCnt>=20 ) ? true : false;
+				if ( fullRig )
+				{
+					const int bindCnt = pSkinData->mAlternateBindMatrix.size();							
+					if ( bindCnt > 0 )
+					{
+						LLVOAvatar::resetJointPositionsToDefault();
+					}
+				}
+			}				
+		}
+	}	
+}
+//-----------------------------------------------------------------------------
 // detachObject()
 //-----------------------------------------------------------------------------
 BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object)
@@ -6035,9 +6064,10 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object)
 		 ++iter)
 	{
 		LLViewerJointAttachment* attachment = iter->second;
-
+		
 		if (attachment->isObjectAttached(viewer_object))
 		{
+			cleanupAttachedMesh( viewer_object );
 			attachment->removeObject(viewer_object);
 			lldebugs << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << llendl;
 			return TRUE;
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index ce5ce045b97902bc5f23580818c4a125629afa48..7ef35178cab10342a4c39baa8b3a96c55c8af185 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -687,6 +687,7 @@ class LLVOAvatar :
 	void 				clampAttachmentPositions();
 	virtual const LLViewerJointAttachment* attachObject(LLViewerObject *viewer_object);
 	virtual BOOL 		detachObject(LLViewerObject *viewer_object);
+	void				cleanupAttachedMesh( LLViewerObject* pVO );
 	static LLVOAvatar*  findAvatarFromAttachment(LLViewerObject* obj);
 protected:
 	LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 5d1020fce810477b9af520c8e28d6a88bb4659a7..3c66c4860ee6a128e30c7c34e24a75350d314302 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -1150,28 +1150,7 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object)
 	const LLUUID attachment_id = viewer_object->getAttachmentItemID();
 	if ( LLVOAvatar::detachObject(viewer_object) )
 	{
-		//If a VO has a skin that we'll reset the joint positions to their default
-		if ( viewer_object->mDrawable )
-		{
-			LLVOVolume* pVObj = viewer_object->mDrawable->getVOVolume();
-			if ( pVObj )
-			{
-				const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID() );
-				if ( pSkinData )
-				{
-					const int jointCnt = pSkinData->mJointNames.size();
-					bool fullRig = ( jointCnt>=20 ) ? true : false;
-					if ( fullRig )
-					{
-						const int bindCnt = pSkinData->mAlternateBindMatrix.size();							
-						if ( bindCnt > 0 )
-						{
-							LLVOAvatar::resetJointPositionsToDefault();
-						}
-					}
-				}				
-			}
-		}
+		LLVOAvatar::cleanupAttachedMesh( viewer_object );
 		
 		// the simulator should automatically handle permission revocation