Пример #1
0
/////////////////////////////////////////////////////////////////////
// Note: 
//    The vertex color data that is used by the ModifyPolyObject 
//    method was created based on this PolyObject's displayed 
//    TriMesh (Mesh). This data is mapped back to the original 
//    PolyMesh (MNMesh).  The mapping relies on the same process 
//    that was used by the method MNMesh::OutToTri() to generate 
//    the Mesh.
// Warning:
//    The mapping used in this method will need to be updated if 
//    anything changes in the way MNMesh generates its displayed Mesh.
// Author: 
//    Wayne Catalfano
// Date:
//    August 30, 2000
//
///////////////////////////////////////////////////////////////////////
void ApplyVCMod::ModifyPolyObject(PolyObject* pPolyObj, TimeValue t)
{
	static int calls = 0;
	iValid = FOREVER;
	Interval valid = GetValidity(t);

	MNMesh& mesh = pPolyObj->GetMesh();
	if (mesh.MNum() < 1) mesh.SetMapNum (1);

	// get the vertex color map
	MNMap* pVCMap = mesh.M(0);

	// initialize to an all white map if necessary
	if (pVCMap->GetFlag(MN_DEAD)) mesh.InitMap(0);

	if (mixedVertexColors.Count() > 0) {
		pVCMap->setNumVerts (mesh.VNum());
		pVCMap->setNumFaces (mesh.FNum());

		// MNMesh keeps the vertices in the same order when it creates
		// the Mesh.  The Mesh vertices Map directly back to the MNMesh
		// vertices in the same order.
		for (int i=0; i<mesh.VNum(); i++) {
			pVCMap->v[i] = i<mixedVertexColors.Count() ?
				Point3(mixedVertexColors[i]->r, mixedVertexColors[i]->g, mixedVertexColors[i]->b) :
				Point3(1.0f, 1.0f, 1.0f);
		}

		for (int i=0; i<mesh.FNum(); i++) {
			if (mesh.F(i)->GetFlag (MN_DEAD)) continue;
			pVCMap->F(i)->SetSize(mesh.F(i)->deg);
			for (int j=0; j<mesh.F(i)->deg;++j) {
				pVCMap->F(i)->tv[j] = mesh.F(i)->vtx[j];
			}
		}
	}
	else if (faceColors.Count() > 0) {
		int numVCVerts = 0;
		for (int i=0; i<mesh.FNum(); i++) {
			if (mesh.F(i)->GetFlag (MN_DEAD)) continue;
			numVCVerts += mesh.F(i)->deg;
		}
		pVCMap->setNumVerts (numVCVerts);
		pVCMap->setNumFaces (mesh.FNum());

		// This mapping process mimicks the process used to generate  
		// the Mesh in the method MNMesh::OutToTri().
		int faceVert = 0;
		int triFaceIndx = 0;
		BitArray faceVertSet;
		for (int i=0; i<mesh.FNum(); i++) {
			if (mesh.F(i)->GetFlag (MN_DEAD)) continue;
			pVCMap->F(i)->SetSize(mesh.F(i)->deg);
			faceVertSet.SetSize(mesh.F(i)->deg);
			faceVertSet.ClearAll();
			int tnum = mesh.F(i)->TriNum()*3;
			Tab<int> triVerts;
			// The method MNFace::GetTriangles is at the heart of the 
			// process used to map Mesh triangles back to MNMesh faces.
			mesh.F(i)->GetTriangles (triVerts);
			for (int j=0; j<tnum; j+=3) {
				for (int k=0; k<3; ++k) {
					int vertIndex = triVerts[j+k];
					// check if we already added a vert for this index
					if (!faceVertSet[vertIndex]) {
						pVCMap->v[faceVert] = triFaceIndx<faceColors.Count() ? 
							Point3(faceColors[triFaceIndx]->colors[k].r, 
								   faceColors[triFaceIndx]->colors[k].g, 
								   faceColors[triFaceIndx]->colors[k].b) :
							Point3(1.0f, 1.0f, 1.0f);

						pVCMap->F(i)->tv[vertIndex] = faceVert;
						faceVertSet.Set(vertIndex);
						faceVert++; 
					}
				}
				++triFaceIndx;
			}
		}
	}

	NotifyDependents(Interval(t,t), PART_VERTCOLOR & PART_EXCLUDE_RADIOSITY, REFMSG_CHANGE);
	NotifyDependents(Interval(t,t), PART_TOPO & PART_EXCLUDE_RADIOSITY, REFMSG_CHANGE);
	pPolyObj->UpdateValidity(VERT_COLOR_CHAN_NUM, valid);
}
Пример #2
0
void ModifierPtex::ModifyObject(TimeValue t, ModContext &mc, ObjectState *os, INode *node) 
{
	Interval valid = FOREVER;

	int uvw_channel = 0;

	if ( m_pblock->GetInt( UVW_TYPE ) == 0 ) 
	{
		uvw_channel = m_pblock->GetInt( UVW_CHANNEL );
	}

	if ( os->obj->IsSubClassOf( polyObjectClassID ) )
	{ 
		PolyObject *polyObj = (PolyObject*)os->obj;
		MNMesh &mnMesh = polyObj->GetMesh();

		bool has_map;
		if ( uvw_channel >= mnMesh.MNum() )
		{
			mnMesh.SetMapNum( uvw_channel + 1 );
			has_map = false;
		} 
		else 
		{
			has_map = mnMesh.M( uvw_channel )->GetFlag( MN_DEAD ) == false;
		}

		MNMap *mc = mnMesh.M( uvw_channel );

		if ( has_map == false )
		{
			mc->setNumFaces( mnMesh.numf );

			for ( int i_f = 0; i_f < mnMesh.numf; i_f++ )
			{
				mc->f[ i_f ].SetSize( mnMesh.f[ i_f ].deg );
			}
		}

		if ( mc->GetFlag( MN_DEAD ) ) mc->ClearFlag( MN_DEAD );

		unsigned int num_tverts = 0;

		for ( int i_f = 0; i_f < mnMesh.numf; i_f++ )
		{
			num_tverts += mc->f[ i_f ].deg;
		}

		mc->setNumVerts( num_tverts );

		unsigned int tvert_id = 0;

		for ( int i_f = 0; i_f < mnMesh.numf; i_f++ )
		{
			unsigned int deg = mc->f[ i_f ].deg;

			for ( unsigned int i_v = 0; i_v < deg; i_v++ )
			{
				mc->f[ i_f ].tv[ i_v ] = tvert_id;

				Point3 tv;

				if      ( i_v == 0 ) tv = Point3( (float)i_f,        0.0f, 0.0f );
				else if ( i_v == 1 ) tv = Point3( (float)i_f + 1.0f, 0.0f, 0.0f );
				else if ( i_v == 2 ) tv = Point3( (float)i_f + 1.0f, 1.0f, 0.0f );
				else                 tv = Point3( (float)i_f,        1.0f, 0.0f );

				tv.z = 0.0f;

				mc->v[ tvert_id ] = tv;
			
				tvert_id++;
			}
		}
	}

	// Update all the caches etc
	Interval iv = LocalValidity(t);
	iv = iv & os->obj->ChannelValidity( t, GEOM_CHAN_NUM );
	iv = iv & os->obj->ChannelValidity( t, TOPO_CHAN_NUM );
	os->obj->UpdateValidity( TEXMAP_CHAN_NUM, iv );
}