void MeshTopoData::ApplyMapping(PatchMesh &patch, int mapChannel)
{





	//get from mesh 

	if (!patch.getMapSupport(mapChannel) )
	{
		patch.setNumMaps (mapChannel+1);

	}

	TVPatch *tvFace = patch.tvPatches[mapChannel];


	int tvFaceCount =  patch.numPatches;

	if (patch.selLevel!=PATCH_PATCH) 
	{
		//copy into mesh struct
		if (!tvFace) 
		{
			// Create tvfaces and init to 0
			patch.setNumMapPatches(mapChannel,patch.getNumPatches());
			tvFace = patch.tvPatches[mapChannel];
			for (int k=0; k<patch.getNumPatches(); k++)
			{	
				for (int j=0; j<TVMaps.f[k]->count; j++) 
				{
					tvFace[k].tv[j] = 0;			
					tvFace[k].interiors[j] = 0;			
					tvFace[k].handles[j*2] = 0;			
					tvFace[k].handles[j*2+1] = 0;			
				}
			}
		}
		for (int k=0; k<tvFaceCount; k++) 
		{
			if (k < TVMaps.f.Count())
			{
				tvFace[k].tv[0] = TVMaps.f[k]->t[0];
				tvFace[k].tv[1] = TVMaps.f[k]->t[1];
				tvFace[k].tv[2] = TVMaps.f[k]->t[2];
				if (TVMaps.f[k]->count == 4) tvFace[k].tv[3] = TVMaps.f[k]->t[3];
				if (TVMaps.f[k]->flags & FLAG_CURVEDMAPPING)
				{
					patch.patches[k].flags &= ~PATCH_LINEARMAPPING;
					if (TVMaps.f[k]->vecs)
					{
						for (int m = 0;m < TVMaps.f[k]->count;m++)
						{
							if (TVMaps.f[k]->flags & FLAG_INTERIOR)
							{
								tvFace[k].interiors[m] = TVMaps.f[k]->vecs->interiors[m];			
							}

							tvFace[k].handles[m*2] = TVMaps.f[k]->vecs->handles[m*2];			
							tvFace[k].handles[m*2+1] = TVMaps.f[k]->vecs->handles[m*2+1];			
						}
					}

				}
				else patch.patches[k].flags |= PATCH_LINEARMAPPING;
			}
			else{
				tvFace[k].tv[0] = 0;
				tvFace[k].tv[1] = 0;
				tvFace[k].tv[2] = 0;
				if (TVMaps.f[k]->count == 4) tvFace[k].tv[3] = 0;
				for (int m = 0;m < TVMaps.f[k]->count;m++)
				{
					tvFace[k].interiors[m] = 0;			
					tvFace[k].handles[m*2] = 0;			
					tvFace[k].handles[m*2+1] = 0;			
				}

			}
		}
		//match verts
		patch.setNumMapVerts (mapChannel,TVMaps.v.Count());
		PatchTVert *tVerts = patch.tVerts[mapChannel];
		for (int k=0; k<TVMaps.v.Count(); k++) 
			tVerts[k].p = GetTVVert(k);
	}
	else
	{
		//copy into mesh struct
		if (!tvFace) 
		{
			// Create tvfaces and init to 0
			patch.setNumMapPatches (mapChannel,patch.getNumPatches());
			tvFace = patch.tvPatches[mapChannel];
			for (int k=0; k<patch.getNumPatches(); k++)
			{	
				for (int j=0; j<TVMaps.f[k]->count; j++) 
				{
					tvFace[k].tv[j] = 0;			
					tvFace[k].interiors[j] = 0;			
					tvFace[k].handles[j*2] = 0;			
					tvFace[k].handles[j*2+1] = 0;			

				}
			}
		}
		int offset = patch.getNumMapVerts (mapChannel);

		for (int k=0; k<tvFaceCount; k++) 
		{
			//copy if face is selected
			if (patch.patchSel[k])
			{
				tvFace[k].tv[0] = TVMaps.f[k]->t[0]+offset;
				tvFace[k].tv[1] = TVMaps.f[k]->t[1]+offset;
				tvFace[k].tv[2] = TVMaps.f[k]->t[2]+offset;
				if (TVMaps.f[k]->count == 4) tvFace[k].tv[3] = TVMaps.f[k]->t[3]+offset;
				if (TVMaps.f[k]->flags & FLAG_CURVEDMAPPING)
				{
					patch.patches[k].flags &= ~PATCH_LINEARMAPPING;
					if (TVMaps.f[k]->vecs)
					{
						for (int m = 0;m < TVMaps.f[k]->count;m++)
						{
							if (TVMaps.f[k]->flags & FLAG_INTERIOR)
							{
								tvFace[k].interiors[m] = TVMaps.f[k]->vecs->interiors[m]+offset;			
							}
							tvFace[k].handles[m*2] = TVMaps.f[k]->vecs->handles[m*2]+offset;			
							tvFace[k].handles[m*2+1] = TVMaps.f[k]->vecs->handles[m*2+1]+offset;			
						}
					}

				}
				else patch.patches[k].flags |= PATCH_LINEARMAPPING;
			}
		}
		//match verts
		patch.setNumMapVerts (mapChannel,TVMaps.v.Count()+offset,TRUE);
		PatchTVert *tVerts = patch.tVerts[mapChannel];
		for ( int k=0; k<TVMaps.v.Count(); k++) 
			tVerts[k+offset].p = GetTVVert(k);

	}
	RemoveDeadVerts(&patch,mapChannel);
}
void MapChannelDelete::ModifyObject(TimeValue t, ModContext &mc, ObjectState * os, INode *node) 
{
	//TODO: Add the code for actually modifying the object

	//get th map id
	int mapID;
	pblock->GetValue(pb_mapid,0,mapID,FOREVER);

	Mesh *mesh = NULL;
	MNMesh *mnmesh = NULL;
	PatchMesh *pmesh = NULL;
		
	TriObject *collapsedtobj = NULL;
	if (os->obj->IsSubClassOf(triObjectClassID))
	{
		TriObject *tobj = (TriObject*)os->obj;
		mesh = &tobj->GetMesh();
	}
	else if (os->obj->IsSubClassOf(polyObjectClassID))
	{
		PolyObject *pobj = (PolyObject*)os->obj;
		mnmesh = &pobj->GetMesh();
	}
	else if (os->obj->IsSubClassOf(patchObjectClassID))
	{
		PatchObject *pobj = (PatchObject*)os->obj;
		pmesh = &pobj->patch;
	}
	

	if (mnmesh)
	{


		int numMaps = mnmesh->numm;

		if (mapID < numMaps)
		{
			mnmesh->M(mapID)->Clear();
			mnmesh->ClearMap(mapID);

		}
	//if last channel reduce the number of channels
			

		if ((numMaps-1) == mapID)
		{
			if (mapID >= 0)
				mnmesh->SetMapNum(mapID);
		}
	}
	else if (mesh)
	{


		int numMaps = mesh->getNumMaps();

		if (mesh->mapSupport(mapID))
		{
			mesh->setNumMapVerts(mapID, 0);
			mesh->setMapSupport(mapID, FALSE);

		}
	//if last channel reduce the number of channels
			

		if ((numMaps-1) == mapID)
		{
			mesh->setNumMaps((numMaps-1), TRUE);
		}
	}
	else if (pmesh)
	{


		int numMaps = pmesh->getNumMaps();

		if (pmesh->getMapSupport(mapID))
		{
//			pmesh->setNumMapVerts(mapID, 0);
//			pmesh->setNumMapPatches(mapID, 0);
			pmesh->setMapSupport(mapID, FALSE);

		}
	//if last channel reduce the number of channels
			

		if ((numMaps-1) == mapID)
		{
			if ((numMaps-1) >= 1)
				pmesh->setNumMaps((numMaps-1), TRUE);
		}
	}


	Interval iv;
	iv = FOREVER;

	os->obj->PointsWereChanged();

	iv &= os->obj->ChannelValidity (t, VERT_COLOR_CHAN_NUM);
	iv &= os->obj->ChannelValidity (t, TEXMAP_CHAN_NUM);
	iv = iv & os->obj->ChannelValidity(t,GEOM_CHAN_NUM);
	iv = iv & os->obj->ChannelValidity(t,TOPO_CHAN_NUM);

	os->obj->UpdateValidity(GEOM_CHAN_NUM,iv);	
	os->obj->UpdateValidity (VERT_COLOR_CHAN_NUM, iv);
	os->obj->UpdateValidity(TEXMAP_CHAN_NUM,iv);

}
void MeshTopoData::SetCache(PatchMesh &patch, int mapChannel)
{
	FreeCache();
	this->patch = new PatchMesh(patch);
	//build TVMAP and edge data

	
	mFSelPrevious.SetSize(patch.patchSel.GetSize());
	mFSelPrevious = patch.patchSel;
	

	if ( (patch.selLevel==PATCH_PATCH) && (patch.patchSel.NumberSet() == 0) ) 
	{
		TVMaps.SetCountFaces(0);
		TVMaps.v.SetCount(0);
		TVMaps.FreeEdges();
		TVMaps.FreeGeomEdges();
		mVSel.SetSize(0);
		mESel.SetSize(0);
		mFSel.SetSize(0);
		mGESel.SetSize(0);
		mGVSel.SetSize(0);
		return;
	}


	//loop through all maps
	//get channel from mesh
	TVMaps.channel = mapChannel;


	//get from mesh based on cahne
	PatchTVert *tVerts = NULL;
	TVPatch *tvFace = NULL;
	if (!patch.getMapSupport(mapChannel))
	{
		patch.setNumMaps(mapChannel+1);
	}

	tVerts = patch.tVerts[mapChannel];
	tvFace = patch.tvPatches[mapChannel];




	if (patch.selLevel!=PATCH_PATCH ) 
	{
		//copy into our structs
		TVMaps.SetCountFaces(patch.getNumPatches());
		TVMaps.v.SetCount(patch.getNumMapVerts(mapChannel));

		mVSel.SetSize(patch.getNumMapVerts (mapChannel));

		TVMaps.geomPoints.SetCount(patch.getNumVerts()+patch.getNumVecs());

		for (int j=0; j<TVMaps.f.Count(); j++) 
		{
			TVMaps.f[j]->flags = 0;


			int pcount = 3;
			if (patch.patches[j].type == PATCH_QUAD) 
			{
				pcount = 4;
			}

			TVMaps.f[j]->t = new int[pcount];
			TVMaps.f[j]->v = new int[pcount];


			if (tvFace == NULL)
			{
				TVMaps.f[j]->t[0] = 0;
				TVMaps.f[j]->t[1] = 0;
				TVMaps.f[j]->t[2] = 0;
				if (pcount ==4) TVMaps.f[j]->t[3] = 0;
				TVMaps.f[j]->FaceIndex = j;
				TVMaps.f[j]->MatID = patch.getPatchMtlIndex(j);
				TVMaps.f[j]->flags = 0;
				TVMaps.f[j]->count = pcount;

				TVMaps.f[j]->vecs = NULL;
				UVW_TVVectorClass *tempv = NULL;
				//new an instance
				if (!(patch.patches[j].flags & PATCH_AUTO))
					TVMaps.f[j]->flags |= FLAG_INTERIOR;

				if (!(patch.patches[j].flags & PATCH_LINEARMAPPING))
				{
					tempv = new UVW_TVVectorClass();
					TVMaps.f[j]->flags |= FLAG_CURVEDMAPPING;
				}
				TVMaps.f[j]->vecs = tempv;	 

				for (int k = 0; k < pcount; k++)
				{
					int index = patch.patches[j].v[k];
					TVMaps.f[j]->v[k] = index;
					TVMaps.geomPoints[index] = patch.verts[index].p;
					//do handles and interiors
					//check if linear
					if (!(patch.patches[j].flags & PATCH_LINEARMAPPING))
					{
						//do geometric points
						index = patch.patches[j].interior[k];
						TVMaps.f[j]->vecs->vinteriors[k] =patch.getNumVerts()+index;
						index = patch.patches[j].vec[k*2];
						TVMaps.f[j]->vecs->vhandles[k*2] =patch.getNumVerts()+index;
						index = patch.patches[j].vec[k*2+1];
						TVMaps.f[j]->vecs->vhandles[k*2+1] =patch.getNumVerts()+index;
						// do texture points do't need to since they don't exist in this case

						TVMaps.f[j]->vecs->interiors[k] =0;								
						TVMaps.f[j]->vecs->handles[k*2] =0;
						TVMaps.f[j]->vecs->handles[k*2+1] =0;

					}

				}

			}
			else
			{
				TVMaps.f[j]->t[0] = tvFace[j].tv[0];
				TVMaps.f[j]->t[1] = tvFace[j].tv[1];
				TVMaps.f[j]->t[2] = tvFace[j].tv[2];
				if (pcount ==4) TVMaps.f[j]->t[3] = tvFace[j].tv[3];
				TVMaps.f[j]->FaceIndex = j;
				TVMaps.f[j]->MatID = patch.getPatchMtlIndex(j);

				TVMaps.f[j]->flags = 0;
				TVMaps.f[j]->count = pcount;


				TVMaps.f[j]->vecs = NULL;
				UVW_TVVectorClass *tempv = NULL;

				if (!(patch.patches[j].flags & PATCH_AUTO))
					TVMaps.f[j]->flags |= FLAG_INTERIOR;
				//new an instance
				if (!(patch.patches[j].flags & PATCH_LINEARMAPPING))
				{
					BOOL mapLinear = FALSE;		
					for (int tvCount = 0; tvCount < patch.patches[j].type*2; tvCount++)
					{
						if (tvFace[j].handles[tvCount] < 0) mapLinear = TRUE;
					}
					if (!(patch.patches[j].flags & PATCH_AUTO))
					{
						for (int tvCount = 0; tvCount < patch.patches[j].type; tvCount++)
						{
							if (tvFace[j].interiors[tvCount] < 0) mapLinear = TRUE;
						}
					}
					if (!mapLinear)
					{
						tempv = new UVW_TVVectorClass();
						TVMaps.f[j]->flags |= FLAG_CURVEDMAPPING;
					}
				}
				TVMaps.f[j]->vecs = tempv;	 


				if ((patch.selLevel==PATCH_PATCH ) && (patch.patchSel[j] == 0))
					TVMaps.f[j]->flags |= FLAG_DEAD;

				for (int k = 0; k < pcount; k++)
				{
					int index = patch.patches[j].v[k];
					TVMaps.f[j]->v[k] = index;
					TVMaps.geomPoints[index] = patch.verts[index].p;
					//							TVMaps.f[j].pt[k] = patch.verts[index].p;
					//do handles and interiors
					//check if linear
					if (TVMaps.f[j]->flags & FLAG_CURVEDMAPPING)
					{
						//do geometric points
						index = patch.patches[j].interior[k];
						TVMaps.f[j]->vecs->vinteriors[k] =patch.getNumVerts()+index;
						index = patch.patches[j].vec[k*2];
						TVMaps.f[j]->vecs->vhandles[k*2] =patch.getNumVerts()+index;
						index = patch.patches[j].vec[k*2+1];
						TVMaps.f[j]->vecs->vhandles[k*2+1] =patch.getNumVerts()+index;
						// do texture points do't need to since they don't exist in this case
						if (TVMaps.f[j]->flags & FLAG_INTERIOR)
						{
							index = tvFace[j].interiors[k];
							TVMaps.f[j]->vecs->interiors[k] =index;
						}
						index = tvFace[j].handles[k*2];
						TVMaps.f[j]->vecs->handles[k*2] =index;
						index = tvFace[j].handles[k*2+1];
						TVMaps.f[j]->vecs->handles[k*2+1] =index;

					}

				}



			}

		}
		for (int geomvecs =0; geomvecs < patch.getNumVecs(); geomvecs++)
		{
			TVMaps.geomPoints[geomvecs+patch.getNumVerts()] = patch.vecs[geomvecs].p;
		}

		for ( int j=0; j<TVMaps.v.Count(); j++) 
		{
			TVMaps.v[j].SetFlag(0);
			if (tVerts)
				TVMaps.v[j].SetP(tVerts[j]);
			else TVMaps.v[j].SetP(Point3(0.0f,0.0f,0.0f));
			TVMaps.v[j].SetInfluence(0.0f);
			TVMaps.v[j].SetControlID(-1);
		}
		if (tvFace == NULL) BuildInitialMapping(&patch);

		TVMaps.mSystemLockedFlag.SetSize(TVMaps.v.Count());
		TVMaps.mSystemLockedFlag.ClearAll();


	}
	else
	{

		//copy into our structs
		TVMaps.SetCountFaces(patch.getNumPatches());

		TVMaps.v.SetCount(patch.getNumMapVerts (mapChannel));

		mVSel.SetSize(patch.getNumMapVerts (mapChannel));

		TVMaps.geomPoints.SetCount(patch.getNumVerts()+patch.getNumVecs());


		for (int j=0; j<TVMaps.f.Count(); j++) 
		{
			TVMaps.f[j]->flags = 0;

			int pcount = 3;

			if (patch.patches[j].type == PATCH_QUAD) 
			{
				pcount = 4;
			}

			TVMaps.f[j]->t = new int[pcount];
			TVMaps.f[j]->v = new int[pcount];

			if (tvFace == NULL)
			{
				TVMaps.f[j]->t[0] = 0;
				TVMaps.f[j]->t[1] = 0;
				TVMaps.f[j]->t[2] = 0;
				if (pcount == 4) TVMaps.f[j]->t[3] = 0;
				TVMaps.f[j]->FaceIndex = j;
				TVMaps.f[j]->MatID = patch.patches[j].getMatID();
				if (patch.patchSel[j])
					TVMaps.f[j]->flags = 0;
				else TVMaps.f[j]->flags = FLAG_DEAD;
				TVMaps.f[j]->count = pcount;

				TVMaps.f[j]->vecs = NULL;
				UVW_TVVectorClass *tempv = NULL;

				if (!(patch.patches[j].flags & PATCH_AUTO))
					TVMaps.f[j]->flags |= FLAG_INTERIOR;

				//new an instance
				if (!(patch.patches[j].flags & PATCH_LINEARMAPPING))
				{
					tempv = new UVW_TVVectorClass();
					TVMaps.f[j]->flags |= FLAG_CURVEDMAPPING;
				}
				TVMaps.f[j]->vecs = tempv;	 


				for (int k = 0; k < pcount; k++)
				{
					int index = patch.patches[j].v[k];
					TVMaps.f[j]->v[k] = index;
					TVMaps.geomPoints[index] = patch.verts[index].p;
					//							TVMaps.f[j].pt[k] = patch.verts[index].p;
					//check if linear
					if (!(patch.patches[j].flags & PATCH_LINEARMAPPING))
					{
						//do geometric points
						index = patch.patches[j].interior[k];
						TVMaps.f[j]->vecs->vinteriors[k] =patch.getNumVerts()+index;
						index = patch.patches[j].vec[k*2];
						TVMaps.f[j]->vecs->vhandles[k*2] =patch.getNumVerts()+index;
						index = patch.patches[j].vec[k*2+1];
						TVMaps.f[j]->vecs->vhandles[k*2+1] =patch.getNumVerts()+index;
						// do texture points do't need to since they don't exist in this case

						TVMaps.f[j]->vecs->interiors[k] =0;								
						TVMaps.f[j]->vecs->handles[k*2] =0;
						TVMaps.f[j]->vecs->handles[k*2+1] =0;

					}

				}

			}
			else
			{
				TVMaps.f[j]->t[0] = tvFace[j].tv[0];
				TVMaps.f[j]->t[1] = tvFace[j].tv[1];
				TVMaps.f[j]->t[2] = tvFace[j].tv[2];
				if (pcount == 4) TVMaps.f[j]->t[3] = tvFace[j].tv[3];
				TVMaps.f[j]->FaceIndex = j;
				TVMaps.f[j]->MatID = patch.patches[j].getMatID();


				if (patch.patchSel[j])
					TVMaps.f[j]->flags = 0;
				else TVMaps.f[j]->flags = FLAG_DEAD;

				int pcount = 3;
				if (patch.patches[j].type == PATCH_QUAD) 
				{
					pcount = 4;
				}
				TVMaps.f[j]->count = pcount;

				TVMaps.f[j]->vecs = NULL;
				UVW_TVVectorClass *tempv = NULL;
				if (!(patch.patches[j].flags & PATCH_AUTO))
					TVMaps.f[j]->flags |= FLAG_INTERIOR;
				//new an instance
				if (!(patch.patches[j].flags & PATCH_LINEARMAPPING))
				{
					BOOL mapLinear = FALSE;		
					for (int tvCount = 0; tvCount < patch.patches[j].type*2; tvCount++)
					{
						if (tvFace[j].handles[tvCount] < 0) mapLinear = TRUE;
					}
					if (!(patch.patches[j].flags & PATCH_AUTO))
					{
						for (int tvCount = 0; tvCount < patch.patches[j].type; tvCount++)
						{
							if (tvFace[j].interiors[tvCount] < 0) mapLinear = TRUE;
						}
					}
					if (!mapLinear)
					{
						tempv = new UVW_TVVectorClass();
						TVMaps.f[j]->flags |= FLAG_CURVEDMAPPING;
					}
				}
				TVMaps.f[j]->vecs = tempv;	 


				for (int k = 0; k < pcount; k++)
				{
					int index = patch.patches[j].v[k];
					TVMaps.f[j]->v[k] = index;
					TVMaps.geomPoints[index] = patch.verts[index].p;
					//							TVMaps.f[j].pt[k] = patch.verts[index].p;
					//do handles and interiors
					//check if linear
					if (TVMaps.f[j]->flags & FLAG_CURVEDMAPPING)
					{
						//do geometric points
						index = patch.patches[j].interior[k];
						TVMaps.f[j]->vecs->vinteriors[k] =patch.getNumVerts()+index;
						index = patch.patches[j].vec[k*2];
						TVMaps.f[j]->vecs->vhandles[k*2] =patch.getNumVerts()+index;
						index = patch.patches[j].vec[k*2+1];
						TVMaps.f[j]->vecs->vhandles[k*2+1] =patch.getNumVerts()+index;
						// do texture points do't need to since they don't exist in this case
						if (TVMaps.f[j]->flags & FLAG_INTERIOR)
						{
							index = tvFace[j].interiors[k];
							TVMaps.f[j]->vecs->interiors[k] =index;
						}
						index = tvFace[j].handles[k*2];
						TVMaps.f[j]->vecs->handles[k*2] =index;
						index = tvFace[j].handles[k*2+1];
						TVMaps.f[j]->vecs->handles[k*2+1] =index;

					}
				}

			}
		}
		for (int j =0; j < patch.getNumVecs(); j++)
		{
			TVMaps.geomPoints[j+patch.getNumVerts()] = patch.vecs[j].p;
		}



		for (int j=0; j<TVMaps.v.Count(); j++) 
		{
//			TVMaps.v[j].SystemLocked(TRUE);
			if (tVerts)
				TVMaps.v[j].SetP(tVerts[j]);
			else TVMaps.v[j].SetP(Point3(.0f,0.0f,0.0f));
			//check if vertex for this face selected
			TVMaps.v[j].SetInfluence(0.0f);
			TVMaps.v[j].SetControlID(-1);

		}


		if (tvFace == NULL) BuildInitialMapping(&patch);
		TVMaps.mSystemLockedFlag.SetSize(TVMaps.v.Count());
		TVMaps.mSystemLockedFlag.SetAll();

		for (int j=0; j<TVMaps.f.Count(); j++) 
		{
			if (!(TVMaps.f[j]->flags & FLAG_DEAD))
			{
				
				int a;
				a = TVMaps.f[j]->t[0];
				TVMaps.v[a].SetFlag(0);
				TVMaps.mSystemLockedFlag.Set(a,FALSE);
				a = TVMaps.f[j]->t[1];
				TVMaps.v[a].SetFlag(0);
				TVMaps.mSystemLockedFlag.Set(a,FALSE);
				a = TVMaps.f[j]->t[2];
				TVMaps.v[a].SetFlag(0);
				TVMaps.mSystemLockedFlag.Set(a,FALSE);

				if (TVMaps.f[j]->count > 3)
				{
					a = TVMaps.f[j]->t[3];
					TVMaps.v[a].SetFlag(0);
					TVMaps.mSystemLockedFlag.Set(a,FALSE);
				}
				if ( (TVMaps.f[j]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[j]->vecs))
				{
					for (int m =0; m < TVMaps.f[j]->count; m++) 
					{
						int hid = TVMaps.f[j]->vecs->handles[m*2];
						TVMaps.v[hid].SetFlag(0) ;
						TVMaps.mSystemLockedFlag.Set(hid,FALSE);

						hid = TVMaps.f[j]->vecs->handles[m*2+1];
						TVMaps.v[hid].SetFlag(0) ;
						TVMaps.mSystemLockedFlag.Set(hid,FALSE);
					}
					if (TVMaps.f[j]->flags & FLAG_INTERIOR) 
					{
						for (int m =0; m < TVMaps.f[j]->count; m++) 
						{
							int iid = TVMaps.f[j]->vecs->interiors[m];
							TVMaps.v[iid].SetFlag(0);
							TVMaps.mSystemLockedFlag.Set(iid,FALSE);
						}

					}


				}
			}
		}

	}

}
void MapChannelPaste::ModifyObject(TimeValue t, ModContext &mc, ObjectState * os, INode *node) 
{
	//TODO: Add the code for actually modifying the object

	//get th map id
	int mapID;
	pblock->GetValue(pb_mapid,0,mapID,FOREVER);
	mapID = buffer.pasteToChannel;

	BOOL useMap;
	pblock->GetValue(pb_usemap,0,useMap,FOREVER);

		//get the mesh
	Mesh *mesh = NULL;
	MNMesh *mnmesh = NULL;
	PatchMesh *pmesh = NULL;
		
	TriObject *collapsedtobj = NULL;
	if (os->obj->IsSubClassOf(triObjectClassID))
	{
		TriObject *tobj = (TriObject*)os->obj;
		mesh = &tobj->GetMesh();
	}
	else if (os->obj->IsSubClassOf(polyObjectClassID))
	{
		PolyObject *pobj = (PolyObject*)os->obj;
		mnmesh = &pobj->GetMesh();
	}
#ifndef NO_PATCHES
	else if (os->obj->IsSubClassOf(patchObjectClassID))
	{
		PatchObject *pobj = (PatchObject*)os->obj;
		pmesh = &pobj->patch;
	}
#endif // NO_PATCHES
	
//	TriObject *tobj = (TriObject*)os->obj;
//	Mesh &mesh = tobj->GetMesh();		

	if (pmesh)
	{
		
		if ( (buffer.numRealFaces == pmesh->numPatches) && (buffer.patchDeg.Count() == pmesh->numPatches) &&
		     ((buffer.pasteToChannelType == PATCHMAPCHANNEL) || (buffer.pasteToChannelType == CHANNEL_MAP)))
		{
			BOOL gvalid = TRUE;
			for (int i = 0; i < pmesh->numPatches; i++)
			{

				int sDeg, tDeg;
				sDeg = buffer.patchDeg[i];		
				tDeg = 3;
				if (pmesh->patches[i].type == PATCH_QUAD)
					tDeg = 4;

				if (tDeg != sDeg)
					gvalid = FALSE;

			}
			if (gvalid)
			{
				if ((buffer.pasteToChannelType == PATCHMAPCHANNEL) || (buffer.pasteToChannelType == CHANNEL_MAP))
				{
					int numMaps = pmesh->getNumMaps();

					BOOL clear = FALSE;
					if (!pmesh->getMapSupport(mapID))
						{
						pmesh->setMapSupport(mapID, TRUE);
						clear = TRUE;
						}

			//if last channel reduce the number of channels
					if (buffer.pasteToSubID == -50)
						pmesh->setNumMapVerts(mapID, buffer.verts.Count());
					else pmesh->setNumMapVerts(mapID, buffer.w.Count());

					PatchTVert *uvw = pmesh->mapVerts(mapID);
					TVPatch *uvwFace = pmesh->tvPatches[mapID];//mesh->mapFaces(mapID);

					int ct = buffer.verts.Count();

					if (buffer.pasteToSubID != -50)
						ct = buffer.w.Count();

					for (int i = 0; i < ct; i++)
					{
						if (buffer.pasteToSubID == -50)
							uvw[i] = buffer.verts[i];
						else
							{
							if (clear)
								uvw[i].p = Point3(0.0f,0.0f,0.0f);
							uvw[i].p[buffer.pasteToSubID] = buffer.w[i];
							}
					}

					for (int i = 0; i < buffer.numFaces; i++)
					{
						uvwFace[i] = buffer.uvwPatchFaces[i];
					}

					


				}

			}

		}
	}
	else if (mnmesh)
	{
		
		
		if (buffer.numRealFaces == mnmesh->numf)
		{
			BOOL gvalid = TRUE;
			for (int i = 0; i < mnmesh->numf; i++)
			{
				int sDeg, tDeg;
				if (buffer.copyType == POLYMAPCHANNEL) 
					sDeg = buffer.uvwMNFaces[i]->deg;
				else sDeg = buffer.geomMNFaces[i]->deg;
				tDeg = mnmesh->f[i].deg;

				if (tDeg != sDeg)
					gvalid = FALSE;

			}
			if (gvalid)
			{
				if ((buffer.pasteToChannelType == POLYMAPCHANNEL) || (buffer.pasteToChannelType == CHANNEL_MAP))
				{
					int numMaps = mnmesh->numm;

					BOOL clear = FALSE;
					if (mapID >= numMaps)
						{
						mnmesh->SetMapNum(mapID+1);
						mnmesh->InitMap(mapID);
						clear = TRUE;
						}
					
//					MNMap *map = mnmesh->M(mapID);
					MNMapFace *uvwFace = mnmesh->M(mapID)->f;
					if (!uvwFace)
						{
						mnmesh->InitMap(mapID);
						uvwFace = mnmesh->M(mapID)->f;
						clear = TRUE;

						}
		

			//if last channel reduce the number of channels
					if (buffer.pasteToSubID == -50)
					{
						if (buffer.copyType == POLYMESH_GEOM)
							mnmesh->M(mapID)->setNumVerts(buffer.mnVerts.Count());
						else mnmesh->M(mapID)->setNumVerts(buffer.verts.Count());
					}
					else mnmesh->M(mapID)->setNumVerts(buffer.w.Count());

					Point3 *uvw = mnmesh->M(mapID)->v;

					int ct = mnmesh->M(mapID)->numv;//buffer.mnVerts.Count();

					if (buffer.pasteToSubID != -50)
						ct = buffer.w.Count();

					for (int i = 0; i < ct; i++)
					{
						if (buffer.pasteToSubID == -50)
						{
							if (buffer.copyType == POLYMESH_GEOM)
								uvw[i] = buffer.mnVerts[i].p;
							else uvw[i] = buffer.verts[i];
						}
						else
							{
							if (clear)
								uvw[i] = Point3(0.0f,0.0f,0.0f);
							uvw[i][buffer.pasteToSubID] = buffer.w[i];
							}
					}

					if ((buffer.copyType == POLYMESH_GEOM) || (buffer.copyType == POLYMESH_SEL))
					{
						for (int i = 0; i < buffer.numFaces; i++)
						{
							int deg = buffer.geomMNFaces[i]->deg;
							
							uvwFace[i].MakePoly(deg,buffer.geomMNFaces[i]->vtx);
						}
					}
					else
					{
						for (int i = 0; i < buffer.numFaces; i++)
						{
							uvwFace[i] = *buffer.uvwMNFaces[i];
						}

					}

				}
				else if ((buffer.pasteToChannelType == POLYGEOMCHANNEL)|| (buffer.pasteToChannelType == CHANNEL_GEOM))
				{

					int ct = buffer.mnVerts.Count();

					if (buffer.copyType == POLYMESH_MAP)
						ct = buffer.verts.Count();

					if (buffer.pasteToSubID != -50)
						ct = buffer.w.Count();

					if (buffer.pasteToSubID == -50)
					{
						if (buffer.copyType == POLYMESH_GEOM)
							mnmesh->setNumVerts(buffer.mnVerts.Count());
						else mnmesh->setNumVerts(buffer.verts.Count());
					}
					else mnmesh->setNumVerts(buffer.w.Count());

					

					MNVert *verts = mnmesh->v;
					MNFace *geomFace = mnmesh->f;

					


					for (int i = 0; i < ct; i++)
					{
						if (buffer.pasteToSubID == -50)
						{
							if (buffer.copyType == POLYMESH_GEOM)
								verts[i] = buffer.mnVerts[i];
							else verts[i].p = buffer.verts[i];
						}
						else verts[i].p[buffer.pasteToSubID] = buffer.w[i];
					}

					if ((buffer.copyType == POLYMESH_GEOM) || (buffer.copyType == POLYMESH_SEL))
					{
						for (int i = 0; i < buffer.numFaces; i++)
						{
							geomFace[i] = *buffer.geomMNFaces[i];
						}
					}
					else
					{
						for (int i = 0; i < buffer.numFaces; i++)
						{
							geomFace[i].MakePoly(buffer.uvwMNFaces[i]->deg,buffer.uvwMNFaces[i]->tv);
					//		geomFace[i].v[0] = buffer.uvwMNFaces[i].t[0];
					//		geomFace[i].v[1] = buffer.uvwMNFaces[i].t[1];
					//		geomFace[i].v[2] = buffer.uvwMNFaces[i].t[2];
						}

					}

				}

				else if ((buffer.pasteToChannelType == POLYSELCHANNEL) || (buffer.pasteToChannelType == CHANNEL_SEL))
				{
					MNVert *verts = mnmesh->v;
					MNFace *geomFace = mnmesh->f;

					mnmesh->SupportVSelectionWeights();


					

					float *vsw = NULL;

					vsw = mnmesh->getVSelectionWeights ();

					mnmesh->ClearVFlags (MN_SEL);

//					mesh->vertSel.ClearAll();

/*					for (int i = 0; i < buffer.w.Count(); i++)
					{
						if (vsw)
						{
							vsw[i] = buffer.w[i];
							if (vsw[i] >= 1.0f)
								mnmesh->v[i].SetFlag (MN_SEL);
								
						}
					}
*/					

					if ((buffer.copyType == POLYMESH_GEOM) || (buffer.copyType == POLYMESH_SEL))
					{
						for (int i = 0; i < buffer.numFaces; i++)
						{
//							geomFace[i] = *buffer.geomMNFaces[i];
							for (int k = 0; k < geomFace[i].deg; k++)
							{
//								geomFace[i].vtx[k] = buffer.uvwMNFaces[i]->tv[k];
								int id = buffer.geomMNFaces[i]->vtx[k];
								int gid = geomFace[i].vtx[k];
								if (vsw)
								{
									vsw[gid] = buffer.w[id];								
								}
							}

						}
					}
					else
					{
						for (int i = 0; i < buffer.numFaces; i++)
						{
							for (int k = 0; k < geomFace[i].deg; k++)
							{
//								geomFace[i].vtx[k] = buffer.uvwMNFaces[i]->tv[k];
								int id = buffer.uvwMNFaces[i]->tv[k];
								int gid = geomFace[i].vtx[k];
								if (vsw)
								{
									vsw[gid] = buffer.w[id];								
								}
								
							}
						}

					}
					
					for (int i = 0; i < mnmesh->numv; i++)
					{
						if (vsw)
						{							
							if (vsw[i] >= 1.0f)
								mnmesh->v[i].SetFlag (MN_SEL);								
						}
					}	
									
					mnmesh->dispFlags =MNDISP_VERTTICKS |MNDISP_SELVERTS ;
					mnmesh->selLevel = MNM_SL_VERTEX ;
				}

			}
		}
	}
	else if (mesh)
	{

		if (buffer.numFaces == mesh->numFaces)
		{
			if ((buffer.pasteToChannelType == TRIMAPCHANNEL) || (buffer.pasteToChannelType == CHANNEL_MAP))
			{
				int numMaps = mesh->getNumMaps();

				BOOL clear = FALSE;
				if (!mesh->mapSupport(mapID))
					{
					mesh->setMapSupport(mapID, TRUE);
					clear = TRUE;
					}

		//if last channel reduce the number of channels
				if (buffer.pasteToSubID == -50)
					mesh->setNumMapVerts(mapID, buffer.verts.Count());
				else mesh->setNumMapVerts(mapID, buffer.w.Count());

				UVVert *uvw = mesh->mapVerts(mapID);
				TVFace *uvwFace = mesh->mapFaces(mapID);

				int ct = buffer.verts.Count();

				if (buffer.pasteToSubID != -50)
					ct = buffer.w.Count();

				for (int i = 0; i < ct; i++)
				{
					if (buffer.pasteToSubID == -50)
						uvw[i] = buffer.verts[i];
					else
						{
						if (clear)
							uvw[i] = Point3(0.0f,0.0f,0.0f);
						uvw[i][buffer.pasteToSubID] = buffer.w[i];
						}
				}

				if ((buffer.copyType == TRIMESH_GEOM) || (buffer.copyType == TRIMESH_SEL))
				{
					for (int i = 0; i < buffer.numFaces; i++)
					{
						uvwFace[i].t[0] = buffer.geomFaces[i].v[0];
						uvwFace[i].t[1] = buffer.geomFaces[i].v[1];
						uvwFace[i].t[2] = buffer.geomFaces[i].v[2];
					}
				}
				else
				{
					for (int i = 0; i < buffer.numFaces; i++)
					{
						uvwFace[i] = buffer.uvwFaces[i];
					}

				}

			}
			else if ((buffer.pasteToChannelType == TRIGEOMCHANNEL)|| (buffer.pasteToChannelType == CHANNEL_GEOM))
			{

				int ct = buffer.verts.Count();

				if (buffer.pasteToSubID != -50)
					ct = buffer.w.Count();

				if (buffer.pasteToSubID == -50)
					mesh->setNumVerts(buffer.verts.Count());
				else mesh->setNumVerts(buffer.w.Count());

				

				Point3 *verts = mesh->verts;
				Face *geomFace = mesh->faces;

				


				for (int i = 0; i < ct; i++)
				{
					if (buffer.pasteToSubID == -50)
						verts[i] = buffer.verts[i];
					else verts[i][buffer.pasteToSubID] = buffer.w[i];
				}

				if ((buffer.copyType == TRIMESH_GEOM) || (buffer.copyType == TRIMESH_SEL))
				{
					for (int i = 0; i < buffer.numFaces; i++)
					{
						geomFace[i] = buffer.geomFaces[i];
					}
				}
				else
				{
					for (int i = 0; i < buffer.numFaces; i++)
					{
						geomFace[i].v[0] = buffer.uvwFaces[i].t[0];
						geomFace[i].v[1] = buffer.uvwFaces[i].t[1];
						geomFace[i].v[2] = buffer.uvwFaces[i].t[2];
					}

				}

			}
			else if ((buffer.pasteToChannelType == TRISELCHANNEL)|| (buffer.pasteToChannelType == CHANNEL_SEL))
			{


				Point3 *verts = mesh->verts;
				Face *geomFace = mesh->faces;

				mesh->SupportVSelectionWeights();


				

				float *vsw = NULL;

				vsw = mesh->getVSelectionWeights ();

				mesh->vertSel.ClearAll();
				for (int i = 0; i <mesh->vertSel.GetSize(); i++)
				{
					if (vsw)		
						vsw[i] = 0.0f;
				}

/*				for (int i = 0; i < buffer.w.Count(); i++)
				{
					if (vsw)
					{
						vsw[i] = buffer.w[i];
						if (vsw[i] >= 1.0f)
							mesh->vertSel.Set(i);
					}
				}
*/				

				if ((buffer.copyType == TRIMESH_GEOM) || (buffer.copyType == TRIMESH_SEL))
				{
					for (int i = 0; i < buffer.numFaces; i++)
					{
//						geomFace[i] = buffer.geomFaces[i];
						int id = buffer.geomFaces[i].v[0];
						if (vsw)
							vsw[id] = buffer.w[id];
						
						id = buffer.geomFaces[i].v[1];
						if (vsw)
							vsw[id] = buffer.w[id];							

						id = buffer.geomFaces[i].v[1];
						if (vsw)
							vsw[id] = buffer.w[id];							
							

					}
				}
				else
				{
					for (int i = 0; i < buffer.numFaces; i++)
					{
//						geomFace[i].v[0] = buffer.uvwFaces[i].t[0];
//						geomFace[i].v[1] = buffer.uvwFaces[i].t[1];
//						geomFace[i].v[2] = buffer.uvwFaces[i].t[2];

						int id = buffer.uvwFaces[i].t[0];
						int gid = mesh->faces[i].v[0];
						if (vsw)
							vsw[gid] = buffer.w[id];							

						id = buffer.uvwFaces[i].t[1];
						gid = mesh->faces[i].v[1];
						if (vsw)
							vsw[gid] = buffer.w[id];							

						id = buffer.uvwFaces[i].t[2];
						gid = mesh->faces[i].v[2];
						if (vsw)
							vsw[gid] = buffer.w[id];							



					}

				}
				
				for (int i = 0; i < mesh->numVerts; i++)
				{
					if (vsw)
					{
//						vsw[i] = buffer.w[i];
						if (vsw[i] >= 1.0f)
							mesh->vertSel.Set(i);
					}
				}
				
				

				mesh->dispFlags = DISP_VERTTICKS|DISP_SELVERTS;
				mesh->selLevel = MESH_VERTEX;

			}

		}
		mesh->InvalidateTopologyCache();
	}

	

	
	


	Interval iv;
	iv = FOREVER;

	os->obj->PointsWereChanged();

	iv &= os->obj->ChannelValidity (t, VERT_COLOR_CHAN_NUM);
	iv &= os->obj->ChannelValidity (t, TEXMAP_CHAN_NUM);
	iv = iv & os->obj->ChannelValidity(t,GEOM_CHAN_NUM);
	iv = iv & os->obj->ChannelValidity(t,TOPO_CHAN_NUM);
	iv = iv & os->obj->ChannelValidity(t,SELECT_CHAN_NUM);

	os->obj->UpdateValidity(GEOM_CHAN_NUM,iv);	
	os->obj->UpdateValidity (VERT_COLOR_CHAN_NUM, iv);
	os->obj->UpdateValidity(TEXMAP_CHAN_NUM,iv);
	os->obj->UpdateValidity (SELECT_CHAN_NUM, iv);


}