diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index a0338294c1ee046a8334a693d7c3da8b1fb96439..b2fe9ba6c245bf847946af5a455a0f59f0ccd359 100755
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2078,7 +2078,7 @@ LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL ge
 	mFaceMask = 0x0;
 	mDetail = detail;
 	mSculptLevel = -2;
-	mIsTetrahedron = FALSE;
+	mIsMeshAssetLoaded = FALSE;
 	mLODScaleBias.setVec(1,1,1);
 	mHullPoints = NULL;
 	mHullIndices = NULL;
@@ -2100,7 +2100,7 @@ LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL ge
 
 	generate();
 	
-	if (mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE)
+	if (mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE || mParams.getSculptType() == LL_SCULPT_TYPE_MESH)
 	{
 		createVolumeFaces();
 	}
@@ -2706,173 +2706,21 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
 	return true;
 }
 
-void tetrahedron_set_normal(LLVolumeFace::VertexData* cv)
-{
-	LLVector4a v0;
-	v0.setSub(cv[1].getPosition(), cv[0].getNormal());
-	LLVector4a v1;
-	v1.setSub(cv[2].getNormal(), cv[0].getPosition());
-	
-	cv[0].getNormal().setCross3(v0,v1);
-	cv[0].getNormal().normalize3fast();
-	cv[1].setNormal(cv[0].getNormal());
-	cv[2].setNormal(cv[1].getNormal());
-}
 
-BOOL LLVolume::isTetrahedron()
+BOOL LLVolume::isMeshAssetLoaded()
 {
-	return mIsTetrahedron;
+	return mIsMeshAssetLoaded;
 }
 
-void LLVolume::makeTetrahedron()
+void LLVolume::setMeshAssetLoaded(BOOL loaded)
 {
-	mVolumeFaces.clear();
-
-	LLVolumeFace face;
-
-	F32 x = 0.25f;
-	LLVector4a p[] = 
-	{ //unit tetrahedron corners
-		LLVector4a(x,x,x),
-		LLVector4a(-x,-x,x),
-		LLVector4a(-x,x,-x),
-		LLVector4a(x,-x,-x)
-	};
-
-	face.mExtents[0].splat(-x);
-	face.mExtents[1].splat(x);
-	
-	LLVolumeFace::VertexData cv[3];
-
-	//set texture coordinates
-	cv[0].mTexCoord = LLVector2(0,0);
-	cv[1].mTexCoord = LLVector2(1,0);
-	cv[2].mTexCoord = LLVector2(0.5f, 0.5f*F_SQRT3);
-
-
-	//side 1
-	cv[0].setPosition(p[1]);
-	cv[1].setPosition(p[0]);
-	cv[2].setPosition(p[2]);
-
-	tetrahedron_set_normal(cv);
-
-	face.resizeVertices(12);
-	face.resizeIndices(12);
-
-	LLVector4a* v = (LLVector4a*) face.mPositions;
-	LLVector4a* n = (LLVector4a*) face.mNormals;
-	LLVector2* tc = (LLVector2*) face.mTexCoords;
-
-	v[0] = cv[0].getPosition();
-	v[1] = cv[1].getPosition();
-	v[2] = cv[2].getPosition();
-	v += 3;
-
-	n[0] = cv[0].getNormal();
-	n[1] = cv[1].getNormal();
-	n[2] = cv[2].getNormal();
-	n += 3;
-
-	if(tc)
-	{
-		tc[0] = cv[0].mTexCoord;
-		tc[1] = cv[1].mTexCoord;
-		tc[2] = cv[2].mTexCoord;
-		tc += 3;
-	}
-	
-	//side 2
-	cv[0].setPosition(p[3]);
-	cv[1].setPosition(p[0]);
-	cv[2].setPosition(p[1]);
-
-	tetrahedron_set_normal(cv);
-
-	v[0] = cv[0].getPosition();
-	v[1] = cv[1].getPosition();
-	v[2] = cv[2].getPosition();
-	v += 3;
-
-	n[0] = cv[0].getNormal();
-	n[1] = cv[1].getNormal();
-	n[2] = cv[2].getNormal();
-	n += 3;
-
-	if(tc)
-	{
-		tc[0] = cv[0].mTexCoord;
-		tc[1] = cv[1].mTexCoord;
-		tc[2] = cv[2].mTexCoord;
-		tc += 3;
-	}
-
-	//side 3
-	cv[0].setPosition(p[3]);
-	cv[1].setPosition(p[1]);
-	cv[2].setPosition(p[2]);
-
-	tetrahedron_set_normal(cv);
-
-	v[0] = cv[0].getPosition();
-	v[1] = cv[1].getPosition();
-	v[2] = cv[2].getPosition();
-	v += 3;
-
-	n[0] = cv[0].getNormal();
-	n[1] = cv[1].getNormal();
-	n[2] = cv[2].getNormal();
-	n += 3;
-
-	if(tc)
-	{
-		tc[0] = cv[0].mTexCoord;
-		tc[1] = cv[1].mTexCoord;
-		tc[2] = cv[2].mTexCoord;
-		tc += 3;
-	}
-	
-	//side 4
-	cv[0].setPosition(p[2]);
-	cv[1].setPosition(p[0]);
-	cv[2].setPosition(p[3]);
-
-	tetrahedron_set_normal(cv);
-
-	v[0] = cv[0].getPosition();
-	v[1] = cv[1].getPosition();
-	v[2] = cv[2].getPosition();
-	v += 3;
-
-	n[0] = cv[0].getNormal();
-	n[1] = cv[1].getNormal();
-	n[2] = cv[2].getNormal();
-	n += 3;
-
-	if(tc)
-	{
-		tc[0] = cv[0].mTexCoord;
-		tc[1] = cv[1].mTexCoord;
-		tc[2] = cv[2].mTexCoord;
-		tc += 3;
-	}
-	
-	//set index buffer
-	for (U16 i = 0; i < 12; i++)
-	{
-		face.mIndices[i] = i;
-	}
-	
-	mVolumeFaces.push_back(face);
-	mSculptLevel = 0;
-	mIsTetrahedron = TRUE;
+	mIsMeshAssetLoaded = loaded;
 }
 
 void LLVolume::copyVolumeFaces(const LLVolume* volume)
 {
 	mVolumeFaces = volume->mVolumeFaces;
 	mSculptLevel = 0;
-	mIsTetrahedron = FALSE;
 }
 
 void LLVolume::cacheOptimize()
@@ -2886,13 +2734,6 @@ void LLVolume::cacheOptimize()
 
 S32	LLVolume::getNumFaces() const
 {
-	U8 sculpt_type = (mParams.getSculptType() & LL_SCULPT_TYPE_MASK);
-
-	if (sculpt_type == LL_SCULPT_TYPE_MESH)
-	{
-		return LL_SCULPT_MESH_MAX_FACES;
-	}
-
 	return (S32)mProfilep->mFaces.size();
 }
 
@@ -7269,7 +7110,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
 		resizeVertices(num_vertices);
 		resizeIndices(num_indices);
 
-		if ((volume->getParams().getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH)
+		if (!volume->isMeshAssetLoaded())
 		{
 			mEdge.resize(num_indices);
 		}
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index f67f8f644dfa44185df04ee40361e681f3b15e37..f0e59a3c005d5ecf7f2d004beadd0f35051bfd88 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -1058,14 +1058,14 @@ class LLVolume : public LLRefCount
 public:
 	virtual bool unpackVolumeFaces(std::istream& is, S32 size);
 
-	virtual void makeTetrahedron();
-	virtual BOOL isTetrahedron();
+	virtual void setMeshAssetLoaded(BOOL loaded);
+	virtual BOOL isMeshAssetLoaded();
 
  protected:
 	BOOL mUnique;
 	F32 mDetail;
 	S32 mSculptLevel;
-	BOOL mIsTetrahedron;
+	BOOL mIsMeshAssetLoaded;
 	
 	LLVolumeParams mParams;
 	LLPath *mPathp;
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 9f790d03fe05a3d47ac1728b428a2ba457b7c9cc..984014f309f8cc05a0d7fb3f3dcf1ed17d861e17 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -1283,30 +1283,38 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
 		return;
 	}
 
-	LLVertexBuffer* buffer = face->getVertexBuffer();
+	LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();
+	LLDrawable* drawable = face->getDrawable();
 
 	U32 data_mask = face->getRiggedVertexBufferDataMask();
 	
-	if (!buffer || 
+	if (buffer.isNull() || 
 		buffer->getTypeMask() != data_mask ||
-		buffer->getRequestedVerts() != vol_face.mNumVertices)
+		buffer->getRequestedVerts() != vol_face.mNumVertices ||
+		buffer->getRequestedIndices() != vol_face.mNumIndices ||
+		(drawable && drawable->isState(LLDrawable::REBUILD_ALL)))
 	{
 		face->setGeomIndex(0);
 		face->setIndicesIndex(0);
-		face->setSize(vol_face.mNumVertices, vol_face.mNumIndices, true);
-
-
-		if (sShaderLevel > 0)
-		{
-			buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB);
+		
+		if (buffer.isNull() || buffer->getTypeMask() != data_mask)
+		{ //make a new buffer
+			if (sShaderLevel > 0)
+			{
+				buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB);
+			}
+			else
+			{
+				buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB);
+			}
+			buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true);
 		}
 		else
-		{
-			buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB);
+		{ //resize existing buffer
+			buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices);
 		}
 
-		buffer->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), true);
-
+		face->setSize(vol_face.mNumVertices, vol_face.mNumIndices);
 		face->setVertexBuffer(buffer);
 
 		U16 offset = 0;
@@ -1407,6 +1415,11 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
 			}
 		}
 	}
+
+	if (drawable && (face->getTEOffset() == drawable->getNumFaces()-1))
+	{
+		drawable->clearState(LLDrawable::REBUILD_ALL);
+	}
 }
 
 void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
@@ -1437,7 +1450,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 		LLVolume* volume = vobj->getVolume();
 		S32 te = face->getTEOffset();
 
-		if (!volume || volume->getNumVolumeFaces() <= te)
+		if (!volume || volume->getNumVolumeFaces() <= te || !volume->isMeshAssetLoaded())
 		{
 			continue;
 		}
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 2b6b2a84e1e5c2ea7286ce1a736b1700a34297f8..90a0d5da59e41afb860e3da26be154181c4aaafa 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1701,6 +1701,7 @@ void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header)
 		{
 			LLPointer<LLVolume> volume = new LLVolume(volume_params, LLVolumeLODGroup::getVolumeScaleFromDetail(i));
 			volume->copyVolumeFaces(data.mModel[i]);
+			volume->setMeshAssetLoaded(TRUE);
 		}
 	}
 
@@ -2154,11 +2155,6 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
 
 	if (volume)
 	{
-		if (volume->getNumVolumeFaces() == 0 && !volume->isTetrahedron())
-		{
-			volume->makeTetrahedron();
-		}
-
 		LLVolumeParams params = volume->getParams();
 
 		LLVolumeLODGroup* group = LLPrimitive::getVolumeManager()->getGroup(params);
@@ -2169,7 +2165,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
 			if (last_lod >= 0)
 			{
 				LLVolume* lod = group->refLOD(last_lod);
-				if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0)
+				if (lod && lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0)
 				{
 					group->derefLOD(lod);
 					return last_lod;
@@ -2181,7 +2177,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
 			for (S32 i = detail-1; i >= 0; --i)
 			{
 				LLVolume* lod = group->refLOD(i);
-				if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0)
+				if (lod && lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0)
 				{
 					group->derefLOD(lod);
 					return i;
@@ -2194,7 +2190,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
 			for (S32 i = detail+1; i < 4; ++i)
 			{
 				LLVolume* lod = group->refLOD(i);
-				if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0)
+				if (lod && lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0)
 				{
 					group->derefLOD(lod);
 					return i;
@@ -2445,7 +2441,6 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol
 		if (volume->getNumVolumeFaces() <= 0)
 		{
 			llwarns << "Mesh loading returned empty volume." << llendl;
-			volume->makeTetrahedron();
 		}
 		
 		{ //update system volume
@@ -2453,6 +2448,7 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol
 			if (sys_volume)
 			{
 				sys_volume->copyVolumeFaces(volume);
+				sys_volume->setMeshAssetLoaded(TRUE);
 				LLPrimitive::getVolumeManager()->unrefVolume(sys_volume);
 			}
 			else
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index cbfd64cffb89562efbeb016960373857fadd5433..b097ebcc1d5ecfb1a6b7670220d646ce5bb9d59f 100755
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -367,6 +367,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
 		//
 		// Unpack texture entry data
 		//
+
 		S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num);
 		if (result & teDirtyBits)
 		{
@@ -972,12 +973,8 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
 		// if it's a mesh
 		if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
 		{ //meshes might not have all LODs, get the force detail to best existing LOD
-
 			LLUUID mesh_id = volume_params.getSculptID();
 
-			//profile and path params don't matter for meshes
-			volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
-
 			lod = gMeshRepo.getActualMeshLOD(volume_params, lod);
 			if (lod == -1)
 			{
@@ -1033,14 +1030,13 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
 	
 		updateSculptTexture();
 
-
 		if (isSculpted())
 		{
 			updateSculptTexture();
 			// if it's a mesh
 			if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
 			{
-				if (getVolume()->getNumVolumeFaces() == 0 || getVolume()->isTetrahedron())
+				if (!getVolume()->isMeshAssetLoaded())
 				{ 
 					//load request not yet issued, request pipeline load this mesh
 					LLUUID asset_id = volume_params.getSculptID();
@@ -3150,7 +3146,7 @@ U32 LLVOVolume::getHighLODTriangleCount()
 	else if (isMesh())
 	{
 		LLVolume* ref = LLPrimitive::getVolumeManager()->refVolume(volume->getParams(), 3);
-		if (ref->isTetrahedron() || ref->getNumVolumeFaces() == 0)
+		if (!ref->isMeshAssetLoaded() || ref->getNumVolumeFaces() == 0)
 		{
 			gMeshRepo.loadMesh(this, volume->getParams(), LLModel::LOD_HIGH);
 		}
@@ -3992,7 +3988,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 
 		LLVOVolume* vobj = drawablep->getVOVolume();
 
-		if (vobj->getVolume() && vobj->getVolume()->isTetrahedron() || (vobj->isMesh() && !gMeshRepo.meshRezEnabled()))
+		if (vobj->isMesh() &&
+			(vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled()))
 		{
 			continue;
 		}