Procedural Mesh Deformation causes UV Seams to Appear

Hello,
I am using Unity 3.3 to develop a web-based medical simulation. As part of our design needs, I am doing procedural mesh deformations in order to simulation biological processes like breathing (a la blend shapes or morph targets). I have scripts that do this, and they appear to work correctly, save for the appearance of light seams on the patient which do not exist when the scripts are not running. Additionally, these light seams appear if the scripts are active, but no vertices are being deformed (i.e. the blend shape is the same as the bash mesh). As an example, consider the following 2 screen grabs.

Base Mesh
![alt text][1]

Base Mesh + Blend Shape
![alt text][2]

What we do know is that seams on the forehead and arm correspond to seams in the UV texture. The scripts that do the deformation follow. As a brief overview, The BlendshapeController asks each attached BlendshapePackage to deform the vertices of the mesh every frame to the correct weight. I would appreciate any insight into how to remove these artifacts. Thanks in advance!

public class BlendshapeController : MonoBehaviour {

private bool usingSkin;
private Vector3[] baseVertices;
private Vector3[] deformVertices;

void Awake() {
	Mesh mesh = FetchMesh();
	baseVertices = new Vector3[mesh.vertexCount];
	Array.Copy(mesh.vertices, baseVertices, mesh.vertexCount);		
	deformVertices = new Vector3[mesh.vertexCount];
}

void Start () {
	BlendshapePackage[] blendPacks = GetComponentsInChildren<BlendshapePackage>(true);
	foreach (BlendshapePackage pack in blendPacks) {
		pack.Init(baseVertices);
	}
}

void Update () {
	Array.Copy(baseVertices, deformVertices, baseVertices.Length);
	BlendshapePackage[] blendPacks = GetComponentsInChildren<BlendshapePackage>(false);
	foreach (BlendshapePackage pack in blendPacks) {
		if (pack.blendWeight > 0) {
			pack.Deform(deformVertices);
		}
	}
	ApplyDeformation();
}

private Mesh FetchMesh() {
	MeshFilter filter = GetComponent<MeshFilter>();
	SkinnedMeshRenderer skinMeshRenderer = GetComponent<SkinnedMeshRenderer>();
	if (filter != null) {
		usingSkin = false;
		return filter.mesh;	
	} else if (skinMeshRenderer != null) {
		usingSkin = true;
		return skinMeshRenderer.sharedMesh;
	} else {
		Debug.LogError("BlendshapeController is not attached to a mesh-bearing GameObject");
		return null;
	}
}

private void ApplyDeformation() {
	MeshFilter filter = GetComponent<MeshFilter>();
	SkinnedMeshRenderer skinMeshRenderer = GetComponent<SkinnedMeshRenderer>();
	if (filter != null) {
		filter.mesh.vertices = deformVertices;
		filter.mesh.RecalculateNormals();
        filter.mesh.RecalculateBounds();
	} else if (skinMeshRenderer != null) {
		skinMeshRenderer.sharedMesh.vertices = deformVertices;
		skinMeshRenderer.sharedMesh.RecalculateNormals();
        skinMeshRenderer.sharedMesh.RecalculateBounds();
	} else {
		Debug.LogError("BlendshapeController is not attached to a mesh-bearing GameObject");
	}
}
}

public class BlendshapePackage : MonoBehaviour
{
public float blendWeight;
public List<Mesh> blendTargets;

private List<Vector3[]> blendDeltas;
private bool inconsistent;

void Awake() {
	inconsistent = false;
	blendDeltas = new List<Vector3[]>(blendTargets.Count);	
}

// Use this for initialization
void Start ()
{
	
}

// Update is called once per frame
void Update ()
{

}

public void Init(Vector3[] baseVert) {
	for (int i = 0; i < blendTargets.Count; i++) {
		Vector3[] blendVert = blendTargets*.vertices;*
  •   	if (blendVert.Length != baseVert.Length) {*
    
  •   		Debug.LogError("Inconsistent vertex lengths between base mesh and blendshapes");*
    
  •   		inconsistent = true;*
    
  •   		return;*
    
  •   	}*
    
  •   	Vector3[] blendDelta = new Vector3[blendVert.Length];*
    
  •   	for (int j = 0; j < blendDelta.Length; j++) {*
    
  •   		blendDelta[j] = blendVert[j] - baseVert[j];	*
    
  •   	}*
    
  •   	blendDeltas.Add(blendDelta);*
    
  •   }*
    
  • }*

  • public void Deform(Vector3 vectors) { // Apply deformations*

  •   if (!inconsistent) {*
    
  •   	for (int i = 0; i < blendDeltas.Count; i++) {* 
    

_ Vector3 blendDelta = blendDeltas*;_
_
for (int j = 0; j < vectors.Length; j++) {_
_ vectors[j] += blendWeight * blendDelta[j];_
_
}_
_
}_
_
} else {_
_
Debug.LogWarning(“Skipping deformation step due to inconsistency”);_
_
}_
_
}_
_
}_
[1]: http://utdallas.edu/~rez081000/LightSeams/contrast_lighting_noblend.jpg*

[2]: http://utdallas.edu/~rez081000/LightSeams/contrast_lighting_blend.jpg

You will need to calculate the smoothing groups from the original mesh which is not trivial. Or you can use one of the systems on the Asset Store that will do the morphing for you but beware as far as I know there is only one that deals with smoothing and uv seams etc correctly.