Пример #1
0
void UVWChannel::SetWithMesh(MNMesh *mesh,int channel)
{
	MNMap *mnmap = mesh->M(channel);
	if(mnmap&&mnmap->numv>0&&mnmap->numf>0)
	{
		int i;
		mNumVerts = mnmap->numv;
		mVerts = new UVVert[mNumVerts];
		for(i=0;i<mNumVerts;++i)
		{
			mVerts[i] = mnmap->v[i];
		}		
		
		mNumFaces = mnmap->numf;
		mFaces = new UVWChannel::Face[mNumFaces];
		for(i=0;i<mNumFaces;++i)
		{
			MNMapFace *face = mnmap->F(i);
			mFaces[i].AllocateVerts(face->deg);
			for(int j=0;j<mFaces[i].mNumVerts;++j)
			{
				mFaces[i].mTVVerts[j] = face->tv[j];
			}
		}
	}
}
Пример #2
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);
}
Пример #3
0
IGeometryChecker::ReturnVal MissingUVCoordinatesChecker::GeometryCheck(TimeValue t,INode *nodeToCheck, IGeometryChecker::OutputVal &val)
{
	val.mIndex.ZeroCount();
	if(IsSupported(nodeToCheck))
	{
		LARGE_INTEGER	ups,startTime;
		QueryPerformanceFrequency(&ups);
		QueryPerformanceCounter(&startTime); //used to see if we need to pop up a dialog 
		bool compute = true;
		bool checkTime = GetIGeometryCheckerManager()->GetAutoUpdate();//only check time for the dialog if auto update is active!
		UVWChannel uvmesh;
		ObjectState os  = nodeToCheck->EvalWorldState(t);
		Object *obj = os.obj;
		if(os.obj->IsSubClassOf(triObjectClassID))
		{
			TriObject *tri = dynamic_cast<TriObject *>(os.obj);
			if(tri)
			{
				BitArray arrayOfVertices;
				arrayOfVertices.SetSize(tri->mesh.numVerts);
				arrayOfVertices.ClearAll();
				IGeometryChecker::ReturnVal returnval=IGeometryChecker::eFail;
				int numChannels = tri->mesh.getNumMaps();
				int index;
				for(int i=0;i<numChannels;++i)
				{
					if(tri->mesh.mapSupport(i))
					{

						MeshMap *map  = &tri->mesh.Map(i);
						if(map->getNumVerts()>0 &&map->getNumFaces()>0)
						{
							returnval= TypeReturned();
							int numFaces = map->getNumFaces();
							TVFace * tvFaces = map->tf;
							UVVert *  uvVerts= map->tv;
						
							#pragma omp parallel for
							for(int faceIndex =0;faceIndex<numFaces;++faceIndex)
							{
								if(compute)
								{
									TVFace& tvFace = tvFaces[faceIndex];
									Point3 tv = uvVerts[tvFace.t[0]];
									if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z))
									{
										index = tri->mesh.faces[faceIndex].v[0];
										if(index>=0&&index<tri->mesh.numVerts)
										{
											#pragma omp critical
											{
												arrayOfVertices.Set(index);
											}
										}
									}
									tv = uvVerts[tvFace.t[1]];
									if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z))
									{
										index = tri->mesh.faces[faceIndex].v[1];
										if(index>=0&&index<tri->mesh.numVerts)
										{
											#pragma omp critical
											{
												arrayOfVertices.Set(index);
											}
										}
									}
									tv = uvVerts[tvFace.t[2]];
									if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z))
									{
										index = tri->mesh.faces[faceIndex].v[2];
										if(index>=0&&index<tri->mesh.numVerts)
										{
											#pragma omp critical
											{
												arrayOfVertices.Set(index);
											}
										}
									}
									if(checkTime==true)
									{
										#pragma omp critical
										{
											DialogChecker::Check(checkTime,compute,numFaces,startTime,ups);
										}
									}
								}
							}
						}
					}
				}
				if(arrayOfVertices.IsEmpty()==false) //we have overlapping faces
				{
					int localsize= arrayOfVertices.GetSize();
					for(int i=0;i<localsize;++i)
					{
						if(arrayOfVertices[i])
							val.mIndex.Append(1,&i);
					}
				}
				return returnval;
			}
			else return IGeometryChecker::eFail;
		}
		else if(os.obj->IsSubClassOf(polyObjectClassID))
		{
			PolyObject *poly = dynamic_cast<PolyObject *>(os.obj);
			if(poly)
			{
				BitArray arrayOfVertices;
				arrayOfVertices.SetSize(poly->GetMesh().numv);
				arrayOfVertices.ClearAll();
				IGeometryChecker::ReturnVal returnval=IGeometryChecker::eFail;
				int numChannels= poly->GetMesh().MNum();
				int index;
				for(int i=0;i<numChannels;++i)
				{
					if(poly->GetMesh().M(i))
					{
						MNMesh *mesh = &(poly->GetMesh());
						MNMap *mnmap = mesh->M(i);
						if(mnmap&&mnmap->numv>0&&mnmap->numf>0)
						{
							returnval= TypeReturned();
							int numFaces = mnmap->numf;
							#pragma omp parallel for
							for(int faceIndex =0;faceIndex<numFaces;++faceIndex)
							{
								if(compute)
								{
									Point3 tv;
									int a,b,c;
									MNMapFace *face = mnmap->F(faceIndex);
									UVVert *  uvVerts=  mnmap->v;
									for(int j=0;j<(face->deg);++j)
									{
										if(j==(face->deg-2))
										{
											a  = j; b = j+1; c = 0;
										}
										else if(j==(face->deg-1))
										{
											a  = j; b = 0; c = 1;
										}
										else
										{
											a  = j; b = j+1; c = j+2;
										}
										tv = uvVerts[face->tv[a]];
										if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z))
										{
											index = mesh->f->vtx[a];
											if(index>=0&&index<mesh->numv)
											{
												#pragma omp critical
												{
													arrayOfVertices.Set(index);
												}
											}
										}
										tv = uvVerts[face->tv[b]];
										if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z))
										{
											index = mesh->f->vtx[b];
											if(index>=0&&index<mesh->numv)
											{
												#pragma omp critical
												{
													arrayOfVertices.Set(index);
												}
											}
										}
										tv = uvVerts[face->tv[c]];
										if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z))
										{
											index = mesh->f->vtx[c];
											if(index>=0&&index<mesh->numv)
											{
												#pragma omp critical
												{
													arrayOfVertices.Set(index);
												}
											}
										}
										if(checkTime==true)
										{
											#pragma omp critical
											{
												DialogChecker::Check(checkTime,compute,numFaces,startTime,ups);
											}
										}
									}
								}
							}	
						}
					}
				}
				if(arrayOfVertices.IsEmpty()==false) //we have overlapping faces
				{
					int localsize= arrayOfVertices.GetSize();
					for(int i=0;i<localsize;++i)
					{
						if(arrayOfVertices[i])
							val.mIndex.Append(1,&i);
					}
				}
				return returnval;
			}
			else return IGeometryChecker::eFail;
		}
	}
	return IGeometryChecker::eFail;
}