Пример #1
0
	void	UnwrapMod::CleanUpDeadVertices()
	{

		for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
		{
			MeshTopoData *ld = mMeshTopoData[ldID];
			BitArray usedList;


			usedList.SetSize(ld->GetNumberTVVerts());//TVMaps.v.Count());
			usedList.ClearAll();

			for (int i = 0; i < ld->GetNumberFaces(); i++)//TVMaps.f.Count(); i++)
			{
				if (!ld->GetFaceDead(i))
				{			
					int degree = ld->GetFaceDegree(i);
					for (int j = 0; j < degree; j++)
					{
						int vertIndex = ld->GetFaceTVVert(i,j);//TVMaps.f[i]->t[j];
						usedList.Set(vertIndex);

						//index into the geometric vertlist
						if ((ld->GetFaceHasVectors(i)/*TVMaps.f[i]->vecs*/) && (j < 4))
						{
							vertIndex = ld->GetFaceTVInterior(i,j);//TVMaps.f[i]->vecs->interiors[j];
							if ((vertIndex>=0) && (vertIndex < usedList.GetSize()))
								usedList.Set(vertIndex);

							vertIndex = ld->GetFaceTVHandle(i,j*2);//TVMaps.f[i]->vecs->handles[j*2];
							if ((vertIndex>=0) && (vertIndex < usedList.GetSize()))
								usedList.Set(vertIndex);
							vertIndex = ld->GetFaceTVHandle(i,j*2+1);//TVMaps.f[i]->vecs->handles[j*2+1];
							if ((vertIndex>=0) && (vertIndex < usedList.GetSize()))
								usedList.Set(vertIndex);
						}

					}
				}
			}

			int vInitalDeadCount = 0;
			int vFinalDeadCount = 0;

			for (int i =0; i < ld->GetNumberTVVerts(); i++)//TVMaps.v.Count(); i++)
			{
				if (ld->GetTVVertDead(i))//TVMaps.v[i].flags & FLAG_DEAD)
					vInitalDeadCount++;
			}

			for (int i =0; i < usedList.GetSize(); i++)
			{
				BOOL isRigPoint = ld->GetTVVertFlag(i) & FLAG_RIGPOINT;
				if (!usedList[i] && (!isRigPoint))
				{
					ld->DeleteTVVert(i,this);
//					TVMaps.v[i].flags |= FLAG_DEAD;
				}
			}

			for (int i =0; i < ld->GetNumberTVVerts(); i++)
			{
				if (ld->GetTVVertDead(i))//TVMaps.v[i].flags & FLAG_DEAD)
					vFinalDeadCount++;
			}


#ifdef DEBUGMODE 

			if (gDebugLevel >= 3)
				ScriptPrint(_T("Cleaning Dead Verts Total Verts %d Initial Dead Verts %d Final Dead Verts %d \n"),vTotalCount,vInitalDeadCount,vFinalDeadCount); 

#endif
		}
	}
Пример #2
0
void  UnwrapMod::fnFlattenMapByMatID(float angleThreshold, float spacing, BOOL normalize, int layoutType, BOOL rotateClusters, BOOL fillHoles)
{

	int holdSubMode = fnGetTVSubMode();
	fnSetTVSubMode(TVVERTMODE);

//	vsel.SetAll();

	Tab<Point3*> normList;
	normList.SetCount(6);

	normList[0] = new Point3(1.0f,0.0f,0.0f);
	normList[1] = new Point3(-1.0f,0.0f,0.0f);
	normList[2] = new Point3(0.0f,1.0f,0.0f);
	normList[3] = new Point3(0.0f,-1.0f,0.0f);
	normList[4] = new Point3(0.0f,0.0f,1.0f);
	normList[5] = new Point3(0.0f,0.0f,-1.0f);



	int largestID = -1;
	for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
	{
		MeshTopoData *ld = mMeshTopoData[ldID];

		for (int i = 0; i < ld->GetNumberFaces(); i++)//TVMaps.f.Count(); i++)
		{
			int matID = ld->GetFaceMatID(i);
			if (matID > largestID)
				largestID = matID;
		}
	}
	BitArray usedMats;
	usedMats.SetSize(largestID+1);
	usedMats.ClearAll();
	for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
	{
		MeshTopoData *ld = mMeshTopoData[ldID];
		for (int i = 0; i < ld->GetNumberFaces(); i++)//TVMaps.f.Count(); i++)
		{
			int matID = ld->GetFaceMatID(i);
			usedMats.Set(matID,TRUE);
		}
	}


	Tab<int> matIDs;
	matIDs.SetCount(usedMats.NumberSet());
	int ct = 0;
	for (int i = 0; i < usedMats.GetSize(); i++)
	{
		if (usedMats[i])
		{
			matIDs[ct] = i;
			ct++;
		}

	}

	//loop through our mat ID
	Tab<ClusterClass*> matIDClusters;


	for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
	{
		MeshTopoData *ld = mMeshTopoData[ldID];
		for (int i = 0; i < matIDs.Count(); i++)
		{

				int matID = matIDs[i];
				FreeClusterList();
				for (int ldIDSel = 0; ldIDSel < mMeshTopoData.Count(); ldIDSel++)
				{
					mMeshTopoData[ldIDSel]->ClearFaceSelection();
				}
				ld->SelectByMatID(matID);
				if (ld->GetFaceSelection().NumberSet())
				{

					ClusterClass *mcluster = new ClusterClass();

					mcluster->ld = ld;
					for (int j = 0; j < ld->GetNumberFaces(); j++)//TVMaps.f.Count(); j++)
					{
						if (ld->GetFaceSelected(j))//(TVMaps.f[j]->MatID == matIDs[i])
						{
							mcluster->faces.Append(1,&j,100);
						}
					}

					matIDClusters.Append(1,&mcluster,5);

					fnFlattenMap(flattenAngleThreshold, &normList, flattenSpacing, FALSE, 2, flattenRotate, flattenCollapse);
				}
			
		}
	}


	FreeClusterList();

	clusterList.SetCount(matIDClusters.Count());
	for (int i = 0; i < matIDClusters.Count(); i++)
	{
		clusterList[i] = new ClusterClass();
		clusterList[i]->ld = matIDClusters[i]->ld;
		clusterList[i]->faces.SetCount(matIDClusters[i]->faces.Count());
		for (int j = 0; j < matIDClusters[i]->faces.Count(); j++)
			clusterList[i]->faces[j] = matIDClusters[i]->faces[j];

	}

	for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
		mMeshTopoData[ldID]->UpdateClusterVertices(clusterList);

	Pack(0, spacing, normalize, rotateClusters, fillHoles,FALSE,FALSE);


	FreeClusterList();

	TimeValue t = GetCOREInterface()->GetTime();
	if (normalize)
	{
		float per = 1.0f-(spacing*2.0f);
		float add = spacing;
		for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
		{
			MeshTopoData *ld = mMeshTopoData[ldID];
			for (int i = 0; i < ld->GetNumberTVVerts(); i++)//TVMaps.v.Count(); i++)
			{
				Point3 p = ld->GetTVVert(i);

				p *= per;
				p.x += add;
				p.y += add;

				ld->SetTVVert(t,i,p,this);

//				if (TVMaps.cont[i]) 
//					TVMaps.cont[i]->SetValue(0,&TVMaps.v[i].p,CTRL_ABSOLUTE);

			}
		}
	}

	for (int i = 0; i < matIDs.Count(); i++)
	{
		if (matIDClusters[i])
			delete matIDClusters[i];
	}
	for (int i = 0; i < 6; i++)
		delete normList[i];

	fnSetTVSubMode(holdSubMode);

}
Пример #3
0
void	UnwrapMod::fnCopy()
{
	int ct = 0;
	int currentLDID = -1;
	for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
	{
		BitArray fsel = mMeshTopoData[ldID]->GetFaceSelection();
		if (fsel.NumberSet())
		{
			currentLDID = ldID;
			ct++;
		}
	}
	

	if (ct > 1)
	{
//pop warnign message
		TSTR error,msg;
		error.printf(_T("%s"),GetString(IDS_PW_ERROR));
		msg.printf(_T("%s"),GetString(IDS_PW_COPYERROR));
		MessageBox(	NULL,msg,error,MB_OK);
		return;
	}
	//check for type


	if ((ct == 0) || (currentLDID==-1))
		return;

	copyPasteBuffer.iRotate = 0;

	
	copyPasteBuffer.copyType = 2;


	//make sure we only have one faces off of one local data selected

	MeshTopoData *ld = mMeshTopoData[currentLDID];

	copyPasteBuffer.mod = this;
	//copy the vertex list over
	copyPasteBuffer.tVertData.SetCount(ld->GetNumberTVVerts());//TVMaps.v.Count());
	for (int i =0; i < ld->GetNumberTVVerts(); i++)//TVMaps.v.Count(); i++)
	{
		copyPasteBuffer.tVertData[i] = ld->GetTVVert(i);//TVMaps.v[i].p;
	}	


//	MeshTopoData *md = (MeshTopoData*)mcList[0]->localData;//copy the face data over that is selected
	copyPasteBuffer.lmd = ld;


	for (int i = 0; i < copyPasteBuffer.faceData.Count(); i++)
	{
		delete copyPasteBuffer.faceData[i];
	}

	BitArray faceSel = ld->GetFaceSelection();
	ct = faceSel.NumberSet();
	if (faceSel.NumberSet() == ld->GetNumberFaces())//TVMaps.f.Count())
		copyPasteBuffer.copyType = 1;
	if (faceSel.NumberSet() == 1)
		copyPasteBuffer.copyType = 0;

	copyPasteBuffer.faceData.SetCount(ct);


	int faceIndex = 0;
	for (int i = 0; i < ld->GetNumberFaces(); i++)//TVMaps.f.Count(); i++)
	{
		if (faceSel[i])
		{
			UVW_TVFaceClass *f = ld->CloneFace(i);//TVMaps.f[i]->Clone();
			copyPasteBuffer.faceData[faceIndex] = f;
			faceIndex++;
		}
	}

}
Пример #4
0
void  UnwrapMod::fnUnfoldSelectedPolygons(int unfoldMethod, BOOL normalize)
{     

	// flatten selected polygons
	if (!ip) return;
	BailStart();

	theHold.Begin();
	HoldPointsAndFaces();   

	Point3 normal(0.0f,0.0f,1.0f);

	for (int ldID =0; ldID < mMeshTopoData.Count(); ldID++)
	{
		MeshTopoData *ld = mMeshTopoData[ldID];
		ld->HoldFaceSel();
	}

	BOOL bContinue = TRUE;
	for (int ldID =0; ldID < mMeshTopoData.Count(); ldID++)
	{

		Tab<Point3> mapNormal;
		mapNormal.SetCount(0);
		MeshTopoData *ld = mMeshTopoData[ldID];

		for (int ldIDPrep =0; ldIDPrep < mMeshTopoData.Count(); ldIDPrep++)
		{
			MeshTopoData *ldPrep = mMeshTopoData[ldIDPrep];
			if (ld != ldPrep)
				ldPrep->ClearFaceSelection();
			else
				ldPrep->RestoreFaceSel();
		}

		//hold our face selection
		//get our processed list 
		BitArray holdFaces = ld->GetFaceSelection();
		BitArray processedFaces = ld->GetFaceSelection();
		while (processedFaces.NumberSet())
		{
			//select the first one
			int seed = -1;
			for (int faceID = 0; faceID < processedFaces.GetSize(); faceID++)
			{
				if (processedFaces[faceID])
				{
					seed = faceID;
					faceID = processedFaces.GetSize();
				}
			}
			BitArray faceSel = ld->GetFaceSel();
			faceSel.ClearAll();
			//select the element the first one
			faceSel.Set(seed,TRUE);
			//select it
			ld->SetFaceSel(faceSel);
			SelectGeomElement(ld);
			faceSel = ld->GetFaceSel();

//			ld->SelectElement(TVFACEMODE,FALSE);
			faceSel &= holdFaces;			
			//remove that from our process list
			for (int faceID = 0; faceID < faceSel.GetSize(); faceID++)
			{
				if (faceSel[faceID])
				{
					processedFaces.Set(faceID,FALSE);
				}
			}
			ld->SetFaceSel(faceSel);
			
			bContinue = BuildCluster( mapNormal, 5.0f, TRUE, TRUE, MeshTopoData::kFaceAngle);
			TSTR statusMessage;



			if (bContinue)
			{


				for (int i =0; i < clusterList.Count(); i++)
				{
					
					ld->ClearFaceSelection();
					for (int j = 0; j < clusterList[i]->faces.Count();j++)
						ld->SetFaceSelected(clusterList[i]->faces[j],TRUE);//	sel.Set(clusterList[i]->faces[j]);
					ld->PlanarMapNoScale(clusterList[i]->normal,this);


					int per = (i * 100)/clusterList.Count();
					statusMessage.printf(_T("%s %d%%."),GetString(IDS_PW_STATUS_MAPPING),per);
					if (Bail(ip,statusMessage))
					{
						i = clusterList.Count();
						bContinue =  FALSE;
					}
				}

				DebugPrint (_T("Final Vct %d \n"),ld->GetNumberTVVerts());

				if ( (bContinue) && (clusterList.Count() > 1) )
				{




						Tab<Point3> objNormList;
						BuildNormals(ld,objNormList);

						//remove internal edges
						Tab<int> clusterGroups;
						clusterGroups.SetCount(ld->GetNumberFaces());
						for (int i =0; i < clusterGroups.Count(); i++)
						{
							clusterGroups[i] = -1;
						}
						
						for (int i = 0; i < clusterList.Count(); i++)
						{
							for (int j = 0; j < clusterList[i]->faces.Count(); j++)
							{
								int faceIndex = clusterList[i]->faces[j];
								clusterGroups[faceIndex] = i;
							}
						}
						BitArray processedClusters;
						processedClusters.SetSize(clusterList.Count());
						processedClusters.ClearAll();

						Tab<BorderClass> edgesToBeProcessed;

						BOOL done = FALSE;
						processedClusters.Set(0);
						clusterList[0]->newX = 0.0f;
						clusterList[0]->newY = 0.0f;
						//    clusterList[0]->angle = 0.0f;
						for (int i = 0; i < clusterList[0]->borderData.Count(); i++)
						{
							int outerFaceIndex = clusterList[0]->borderData[i].outerFace;
							int connectedClusterIndex = clusterGroups[outerFaceIndex];
							if ((connectedClusterIndex != 0) && (connectedClusterIndex != -1))
							{
								edgesToBeProcessed.Append(1,&clusterList[0]->borderData[i]);
							}
						}
					
						BitArray seedFaceList;
						seedFaceList.SetSize(clusterGroups.Count());
						seedFaceList.ClearAll();
						for (int i = 0; i < seedFaces.Count(); i++)
						{
							seedFaceList.Set(seedFaces[i]);
						}

						while (!done)
						{
							Tab<int> clustersJustProcessed;
							clustersJustProcessed.ZeroCount();
							done = TRUE;

							int edgeToAlign = -1;
							float angDist = PI*2;
							if (unfoldMethod == 1)
								angDist =  PI*2;
							else if (unfoldMethod == 2) angDist = 0;
							int i;
							for (i = 0; i < edgesToBeProcessed.Count(); i++)
							{
								int outerFace = edgesToBeProcessed[i].outerFace;
								int connectedClusterIndex = clusterGroups[outerFace];
								if (!processedClusters[connectedClusterIndex])
								{
									int innerFaceIndex = edgesToBeProcessed[i].innerFace;
									int outerFaceIndex = edgesToBeProcessed[i].outerFace;
									//get angle
									Point3 innerNorm, outerNorm;
									innerNorm = objNormList[innerFaceIndex];
									outerNorm = objNormList[outerFaceIndex];
									float dot = DotProd(innerNorm,outerNorm);

									float angle = 0.0f;

									if (dot == -1.0f)
										angle = PI;
									else if (dot >= 1.0f)
										angle = 0.f;                  
									else angle = acos(dot);

									if (unfoldMethod == 1)
									{
										if (seedFaceList[outerFaceIndex])
											angle = 0.0f;
										if (angle < angDist)
										{
											angDist = angle;
											edgeToAlign = i;
										}
									}

									else if (unfoldMethod == 2)
									{
										if (seedFaceList[outerFaceIndex])
											angle = 180.0f;
										if (angle > angDist)
										{
											angDist = angle;
											edgeToAlign = i;
										}
									}

								}
							}
							if (edgeToAlign != -1)
							{
								int innerFaceIndex = edgesToBeProcessed[edgeToAlign].innerFace;
								int outerFaceIndex = edgesToBeProcessed[edgeToAlign].outerFace;
								int edgeIndex = edgesToBeProcessed[edgeToAlign].edge;


								int connectedClusterIndex = clusterGroups[outerFaceIndex];

								seedFaceList.Set(outerFaceIndex, FALSE);

								processedClusters.Set(connectedClusterIndex);
								clustersJustProcessed.Append(1,&connectedClusterIndex);	
								ld->AlignCluster(clusterList,connectedClusterIndex,innerFaceIndex, outerFaceIndex,edgeIndex,this);
								done = FALSE;
							}

							//build new cluster list
							for (int j = 0; j < clustersJustProcessed.Count(); j++)
							{
								int clusterIndex = clustersJustProcessed[j];
								for (int i = 0; i < clusterList[clusterIndex]->borderData.Count(); i++)
								{
									int outerFaceIndex = clusterList[clusterIndex]->borderData[i].outerFace;
									int connectedClusterIndex = clusterGroups[outerFaceIndex];
									if ((connectedClusterIndex != 0) && (connectedClusterIndex != -1) && (!processedClusters[connectedClusterIndex]))
									{
										edgesToBeProcessed.Append(1,&clusterList[clusterIndex]->borderData[i]);
									}
								}
							}
						}
					
				}

				ld->ClearSelection(TVVERTMODE);

				for (int i = 0; i < clusterList.Count(); i++)
				{
					MeshTopoData *ld = clusterList[i]->ld;
					ld->UpdateClusterVertices(clusterList);
					for (int j =0; j < clusterList[i]->faces.Count(); j++)
					{
						int faceIndex = clusterList[i]->faces[j];
						int degree = ld->GetFaceDegree(faceIndex);
						for (int k =0; k < degree; k++)
						{
							int vertexIndex = ld->GetFaceTVVert(faceIndex,k);//TVMaps.f[faceIndex]->t[k];
							ld->SetTVVertSelected(vertexIndex,TRUE);//vsel.Set(vertexIndex);
						}
					}
				}

				//now weld the verts
				if (normalize)
				{
					NormalizeCluster();
				}


				ld->WeldSelectedVerts(0.001f,this);

			}
	
			FreeClusterList();
		}
	}

	if (bContinue)
	{  
		theHold.Accept(GetString(IDS_PW_PLANARMAP));		

		theHold.Suspend();
		fnSyncTVSelection();
		theHold.Resume();
	}
	else
	{
		theHold.Cancel();
		
	}

	
	for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
	{			
		mMeshTopoData[ldID]->BuildTVEdges();
		mMeshTopoData[ldID]->RestoreFaceSel();
	}

	theHold.Suspend();
	fnSyncGeomSelection();
	theHold.Resume();

	if (matid != -1) // if we have a matID fileter set we need to rebuild since topology has changed
		SetMatFilters();

	NotifyDependents(FOREVER,PART_SELECT,REFMSG_CHANGE);
	InvalidateView();

}