Exemple #1
0
int EditPatchMod::DoAttach(INode *node, PatchMesh *attPatch, RPatchMesh *rattPatch, bool & canUndo)
{
    ModContextList mcList;
    INodeTab nodes;

    if (!ip)
        return 0;

    ip->GetModContexts(mcList, nodes);

    if (mcList.Count() != 1)
    {
        nodes.DisposeTemporary();
        return 0;
    }

    EditPatchData *patchData =(EditPatchData*)mcList[0]->localData;
    if (!patchData)
    {
        nodes.DisposeTemporary();
        return 0;
    }
    patchData->BeginEdit(ip->GetTime());

    // If the mesh isn't yet cached, this will cause it to get cached.
    RPatchMesh *rpatch;
    PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch);
    if (!patch)
    {
        nodes.DisposeTemporary();
        return 0;
    }
    patchData->RecordTopologyTags(patch);
    RecordTopologyTags();

    // Transform the shape for attachment:
    // If reorienting, just translate to align pivots
    // Otherwise, transform to match our transform
    Matrix3 attMat(1);
    if (attachReorient)
    {
        Matrix3 thisTM = nodes[0]->GetNodeTM(ip->GetTime());
        Matrix3 thisOTMBWSM = nodes[0]->GetObjTMBeforeWSM(ip->GetTime());
        Matrix3 thisPivTM = thisTM * Inverse(thisOTMBWSM);
        Matrix3 otherTM = node->GetNodeTM(ip->GetTime());
        Matrix3 otherOTMBWSM = node->GetObjTMBeforeWSM(ip->GetTime());
        Matrix3 otherPivTM = otherTM * Inverse(otherOTMBWSM);
        Point3 otherObjOffset = node->GetObjOffsetPos();
        attMat = Inverse(otherPivTM) * thisPivTM;
    }
    else
    {
        attMat = node->GetObjectTM(ip->GetTime()) *
                 Inverse(nodes[0]->GetObjectTM(ip->GetTime()));
    }

    // RB 3-17-96 : Check for mirroring
    AffineParts parts;
    decomp_affine(attMat, &parts);
    if (parts.f < 0.0f)
    {
        int v[8], ct, ct2, j;
        Point3 p[9];

        for (int i = 0; i < attPatch->numPatches; i++)
        {

            // Re-order rpatch
            if (attPatch->patches[i].type == PATCH_QUAD)
            {
                UI_PATCH rpatch=rattPatch->getUIPatch (i);
                int ctU=rpatch.NbTilesU<<1;
                int ctV=rpatch.NbTilesV<<1;
                int nU;
                for (nU=0; nU<ctU; nU++)
                {
                    for (int nV=0; nV<ctV; nV++)
                    {
                        rattPatch->getUIPatch (i).getTileDesc (nU+nV*ctU)=rpatch.getTileDesc (ctU-1-nU+(ctV-1-nV)*ctU);
                    }
                }
                for (nU=0; nU<ctU+1; nU++)
                {
                    for (int nV=0; nV<ctV+1; nV++)
                    {
                        rattPatch->getUIPatch (i).setColor (nU+nV*(ctU+1), rpatch.getColor (ctU-nU+(ctV-nV)*ctU));
                    }
                }
            }

            // Re-order vertices
            ct = attPatch->patches[i].type == PATCH_QUAD ? 4 : 3;
            for (j = 0; j < ct; j++)
            {
                v[j] = attPatch->patches[i].v[j];
            }
            for (j = 0; j < ct; j++)
            {
                attPatch->patches[i].v[j] = v[ct - j - 1];
            }

            // Re-order vecs
            ct  = attPatch->patches[i].type == PATCH_QUAD ? 8 : 6;
            ct2 = attPatch->patches[i].type == PATCH_QUAD ? 5 : 3;
            for (j = 0; j < ct; j++)
            {
                v[j] = attPatch->patches[i].vec[j];
            }
            for (j = 0; j < ct; j++, ct2--)
            {
                if (ct2 < 0)
                    ct2 = ct - 1;
                attPatch->patches[i].vec[j] = v[ct2];
            }

            // Re-order enteriors
            if (attPatch->patches[i].type == PATCH_QUAD)
            {
                ct = 4;
                for (j = 0; j < ct; j++)
                {
                    v[j] = attPatch->patches[i].interior[j];
                }
                for (j = 0; j < ct; j++)
                {
                    attPatch->patches[i].interior[j] = v[ct - j - 1];
                }
            }

            // Re-order aux
            if (attPatch->patches[i].type == PATCH_TRI)
            {
                ct = 9;
                for (j = 0; j < ct; j++)
                {
                    p[j] = attPatch->patches[i].aux[j];
                }
                for (j = 0; j < ct; j++)
                {
                    attPatch->patches[i].aux[j] = p[ct - j - 1];
                }
            }

            // Re-order TV faces if present
            for (int chan = 0; chan < patch->getNumMaps(); ++chan)
            {
                if (attPatch->tvPatches[chan])
                {
                    ct = 4;
                    for (j = 0; j < ct; j++)
                    {
                        v[j] = attPatch->tvPatches[chan][i].tv[j];
                    }
                    for (j = 0; j < ct; j++)
                    {
                        attPatch->tvPatches[chan][i].tv[j] = v[ct - j - 1];
                    }
                }
            }
        }
    }

    int i;
    for (i = 0; i < attPatch->numVerts; ++i)
        attPatch->verts[i].p = attPatch->verts[i].p * attMat;
    for (i = 0; i < attPatch->numVecs; ++i)
        attPatch->vecs[i].p = attPatch->vecs[i].p * attMat;
    attPatch->computeInteriors();

    theHold.Begin();

    // Combine the materials of the two nodes.
    int mat2Offset = 0;
    Mtl *m1 = nodes[0]->GetMtl();
    Mtl *m2 = node->GetMtl();
    bool condenseMe = FALSE;
    if (m1 && m2 &&(m1 != m2))
    {
        if (attachMat == ATTACHMAT_IDTOMAT)
        {
            int ct = 1;
            if (m1->IsMultiMtl())
                ct = m1->NumSubMtls();
            for (int i = 0; i < patch->numPatches; ++i)
            {
                int mtid = patch->getPatchMtlIndex(i);
                if (mtid >= ct)
                    patch->setPatchMtlIndex(i, mtid % ct);
            }
            FitPatchIDsToMaterial(*attPatch, m2);
            if (condenseMat)
                condenseMe = TRUE;
        }
        // the theHold calls here were a vain attempt to make this all undoable.
        // This should be revisited in the future so we don't have to use the SYSSET_CLEAR_UNDO.
        theHold.Suspend();
        if (attachMat == ATTACHMAT_MATTOID)
        {
            m1 = FitMaterialToPatchIDs(*patch, m1);
            m2 = FitMaterialToPatchIDs(*attPatch, m2);
        }

        Mtl *multi = CombineMaterials(m1, m2, mat2Offset);
        if (attachMat == ATTACHMAT_NEITHER)
            mat2Offset = 0;
        theHold.Resume();
        // We can't be in face subobject mode, else we screw up the materials:
        DWORD oldSL = patch->selLevel;
        DWORD roldSL = patch->selLevel;
        patch->selLevel = PATCH_OBJECT;
        rpatch->SetSelLevel (EP_OBJECT);
        nodes[0]->SetMtl(multi);
        patch->selLevel = oldSL;
        rpatch->SetSelLevel (roldSL);
        m1 = multi;
        canUndo = FALSE;	// Absolutely cannot undo material combinations.
    }
    if (!m1 && m2)
    {
        // We can't be in face subobject mode, else we screw up the materials:
        DWORD oldSL = patch->selLevel;
        DWORD roldSL = rpatch->GetSelLevel();
        patch->selLevel = PATCH_OBJECT;
        rpatch->SetSelLevel (EP_OBJECT);
        nodes[0]->SetMtl(m2);
        patch->selLevel = oldSL;
        rpatch->SetSelLevel (roldSL);
        m1 = m2;
    }

    // Start a restore object...
    if (theHold.Holding())
        theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "DoAttach"));

    // Do the attach
    patch->Attach(attPatch, mat2Offset);
    rpatch->Attach(rattPatch, *patch);
    patchData->UpdateChanges(patch, rpatch);
    patchData->TempData(this)->Invalidate(PART_TOPO | PART_GEOM);

    // Get rid of the original node
    ip->DeleteNode(node);

    ResolveTopoChanges();
    theHold.Accept(GetString(IDS_TH_ATTACH));

    if (m1 && condenseMe)
    {
        // Following clears undo stack.
        patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch);
        m1 = CondenseMatAssignments(*patch, m1);
    }

    nodes.DisposeTemporary();
    ClearPatchDataFlag(mcList, EPD_BEENDONE);
    NotifyDependents(FOREVER, PART_TOPO | PART_GEOM, REFMSG_CHANGE);
    ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
    return 1;
}
void PasteSkinWeights::ModifyObject(TimeValue t, ModContext &mc, ObjectState * os, INode *node) 
{
	//TODO: Add the code for actually modifying the object


	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;
		mnmesh->SetMapNum(numMaps+1);

		int numGFaces = mnmesh->numf;
		int numGVerts = mnmesh->numv;

		numMaps = boneList.Count()/3+1;
		
		mnmesh->SetMapNum(numMaps);
		for (int i = 0; i < boneList.Count(); i++)
		{	
	
			int mapID = i/3;
			int subID = i%3;

			if (subID==0)	//create our face data
			{
				mnmesh->InitMap(mapID);
				mnmesh->M(mapID)->setNumVerts(numGVerts);
//				mnmesh->setNumMapVerts(mapID,numGVerts);
			}
//			TVFace *tvFace = mnmesh->mapFaces(mapID);
			MNMapFace *uvwFace = mnmesh->M(mapID)->f;
			UVVert *tvVerts = mnmesh->M(mapID)->v;//mnmesh->mapVerts(mapID);
			if (subID==0)	//create our face data
			{
				

				
		//copy our original
			//copy our geo faces to the texture faces
				for (int j = 0; j < numGFaces; j++)
				{
					int deg = mnmesh->f[j].deg;
					uvwFace[j].MakePoly(deg,mnmesh->f[j].vtx);
				}	
				for (int j = 0; j < numGVerts; j++)
				{
					tvVerts[j] = Point3(0.0f,0.0f,0.0f);
				}
			}
			
			for (int j = 0; j < boneList[i]->weights.Count(); j++)
			{
				int vertIndex = boneList[i]->weights[j].vertIndex;
				float vertWeight = boneList[i]->weights[j].vertWeight;
				tvVerts[vertIndex][subID] = vertWeight;
			}
		}

		
	}
	else if (mesh)
	{
		int numMaps = mesh->getNumMaps();

		int numGFaces = mesh->numFaces;
		int numGVerts = mesh->numVerts;

		numMaps = boneList.Count()/3+1;
		
		mesh->setNumMaps(numMaps, FALSE);
		for (int i = 0; i < boneList.Count(); i++)
		{	
	
			int mapID = i/3;
			int subID = i%3;

			if (subID==0)	//create our face data
			{
				mesh->setMapSupport(mapID);
				mesh->setNumMapVerts(mapID,numGVerts);
			}
			TVFace *tvFace = mesh->mapFaces(mapID);
			UVVert *tvVerts = mesh->mapVerts(mapID);
			if (subID==0)	//create our face data
			{
				

				
		//copy our original
			//copy our geo faces to the texture faces
				for (int j = 0; j < numGFaces; j++)
				{
					for (int k = 0; k < 3; k++)
					{
						tvFace[j].t[k] = mesh->faces[j].v[k];
					}
				}	
				for (int j = 0; j < numGVerts; j++)
				{
					tvVerts[j] = Point3(0.0f,0.0f,0.0f);
				}
			}
			
			for (int j = 0; j < boneList[i]->weights.Count(); j++)
			{
				int vertIndex = boneList[i]->weights[j].vertIndex;
				float vertWeight = boneList[i]->weights[j].vertWeight;
				tvVerts[vertIndex][subID] = vertWeight;
			}
				
			

			
		}
	}
	else if (pmesh)
	{
		int numMaps = pmesh->getNumMaps();

		int numGFaces = pmesh->numPatches;
		int numGVerts = pmesh->numVerts+pmesh->numVecs;

		numMaps = boneList.Count()/3+1;
		
		pmesh->setNumMaps(numMaps, FALSE);

		for (int i = 0; i < boneList.Count(); i++)
		{	
	
			int mapID = i/3;
			int subID = i%3;

			if (subID==0)	//create our face data
			{
				pmesh->setMapSupport(mapID);
				pmesh->setNumMapVerts(mapID,numGVerts);
			}

			TVPatch *tvFace = pmesh->tvPatches[mapID];;//TVFace *tvFace = pmesh->mapFaces(mapID);
			PatchTVert *tvVerts = pmesh->mapVerts(mapID);
			if (subID==0)	//create our face data
			{
				

				
		//copy our original
			//copy our geo faces to the texture faces
				for (int j = 0; j < numGFaces; j++)
				{
					int deg = 3;
						if (pmesh->patches[j].type == PATCH_QUAD)
						deg = 4;


					for (int k = 0; k < deg; k++)
					{
						int vindex = pmesh->patches[j].v[k];
						tvFace[j].tv[k] = pmesh->patches[j].v[k];
						tvFace[j].interiors[k] = pmesh->patches[j].interior[k]+pmesh->numVerts;
						tvFace[j].handles[k*2] = pmesh->patches[j].vec[k*2]+pmesh->numVerts;
						tvFace[j].handles[k*2+1] = pmesh->patches[j].vec[k*2+1]+pmesh->numVerts;
					}
				}	
				for (int j = 0; j < numGVerts; j++)
				{
					tvVerts[j] = Point3(0.0f,0.0f,0.0f);
				}
			}
			
			for (int j = 0; j < boneList[i]->weights.Count(); j++)
			{
				int vertIndex = boneList[i]->weights[j].vertIndex;
				float vertWeight = boneList[i]->weights[j].vertWeight;
//DebugPrint(_T("bone %d  vert %d weight %f\n"),i,vertIndex,vertWeight);
				tvVerts[vertIndex].p[subID] = vertWeight;
			}
				
			

			
		}
		
	}


	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);

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


	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;
	}

	//TriObject *tobj = (TriObject*)os->obj;
	//Mesh &mesh = tobj->GetMesh();		

	if (mnmesh)
	{
		int numMaps = mnmesh->numm;
		mnmesh->SetMapNum(numMaps+1);
		mnmesh->InitMap(numMaps);
		
	}
	else if (mesh)
	{
		int numMaps = mesh->getNumMaps();

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

		pmesh->setNumMaps(numMaps+1, TRUE);
//		pmesh->setNumMapPatches(numMaps,0);
//		pmesh->setNumMapVerts(numMaps,0);
	}


	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 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 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);


}