예제 #1
0
	void	UnwrapMod::fnPasteInstance()
	{
		//make sure mods are the same
		theHold.Begin();
		HoldPointsAndFaces();

		for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
		{
			MeshTopoData *ld = mMeshTopoData[ldID];
			if ((this == copyPasteBuffer.mod) && (ld == copyPasteBuffer.lmd))
			{

				BitArray faceSel = ld->GetFaceSelection();

				//loop through selected faces
				int copyIndex = 0;
				for (int i =0; i < faceSel.GetSize(); i++)
				{
					if (faceSel[i])
					{
						//make sure selected faces count = buffer face
						if (( i < ld->GetNumberFaces()/*TVMaps.f.Count()*/) && (copyIndex < copyPasteBuffer.faceData.Count()))
						{
							int degree = ld->GetFaceDegree(i);
							if (degree == copyPasteBuffer.faceData[copyIndex]->count)
							{
								//if so set the face data indices as the same
								for (int j = 0; j < degree; j++)
								{
									//index into the texture vertlist
									ld->SetFaceTVVert(i,j,copyPasteBuffer.faceData[copyIndex]->t[j]);//TVMaps.f[i]->t[j] = copyPasteBuffer.faceData[copyIndex]->t[j];
									//index into the geometric vertlist
									if ((ld->GetFaceHasVectors(i)/*TVMaps.f[i]->vecs*/) && (j < 4))
									{
										ld->SetFaceTVInterior(i,j,copyPasteBuffer.faceData[copyIndex]->vecs->interiors[j]);//TVMaps.f[i]->vecs->interiors[j] = copyPasteBuffer.faceData[copyIndex]->vecs->interiors[j];

										ld->SetFaceTVHandle(i,j*2,copyPasteBuffer.faceData[copyIndex]->vecs->handles[j*2]);//TVMaps.f[i]->vecs->handles[j*2] = copyPasteBuffer.faceData[copyIndex]->vecs->handles[j*2];
										ld->SetFaceTVHandle(i,j*2+1,copyPasteBuffer.faceData[copyIndex]->vecs->handles[j*2+1]);//TVMaps.f[i]->vecs->handles[j*2+1] = copyPasteBuffer.faceData[copyIndex]->vecs->handles[j*2+1];

									}
								}
								copyIndex++;
							}
						}
					}
				}				
				ld->SetTVEdgeInvalid();

			}

		}
		CleanUpDeadVertices();
		theHold.Accept(GetString(IDS_PW_PASTE));
		NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);
		InvalidateView();
		GetCOREInterface()->RedrawViews(GetCOREInterface()->GetTime());

	}
예제 #2
0
void UnwrapMod::fnGizmoCenter()
{
	//get our tm
	//set the tm scale



	TimeValue t = GetCOREInterface()->GetTime();



	
	//get our selection
	Box3 bounds;
	bounds.Init();
	//get the bounding box
	Point3 pnorm(0.0f,0.0f,0.0f);
	int ct = 0;
	for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
	{
		MeshTopoData *ld = mMeshTopoData[ldID];
		Matrix3 tm = mMeshTopoData.GetNodeTM(t,ldID);

		for (int k = 0; k < ld->GetNumberFaces(); k++) 
		{
			if (ld->GetFaceSelected(k))
			{
				// Grap the three points, xformed
				int pcount = 3;
				//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
				pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

				Point3 temp_point[4];
				for (int j=0; j<pcount; j++) 
				{
					int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
					bounds += ld->GetGeomVert(index) * tm; //gverts.d[index].p * tm;
					if (j < 4)
						temp_point[j] = ld->GetGeomVert(index) * tm; //gverts.d[index].p;
				}
				pnorm += Normalize(temp_point[1]-temp_point[0]^temp_point[2]-temp_point[1]);
				ct++;
			}
		}	
	}


	if (ct == 0) return;

	theHold.Begin();
	SuspendAnimate();
	AnimateOff();
	pnorm = pnorm / (float) ct;//gfaces.Count();
	

	//if just a primary axis set the tm;
	Point3 center = bounds.Center();
	// build the scale



	//get our tm
	Matrix3 tm(1);
	tm = *fnGetGizmoTM();
	Matrix3 initialTM = tm;

	Point3 vec2;
	vec2 = Normalize(tm.GetRow(0)); 
	tm.SetRow(0,vec2);

	vec2 = Normalize(tm.GetRow(1)) ;
	tm.SetRow(1,vec2);

	vec2 = Normalize(tm.GetRow(2)); 
	tm.SetRow(2,vec2);

	tm.SetRow(3,center);


 	Matrix3 itm = Inverse(tm);
	//find our x and y scale
	Box3 localBounds;
	localBounds.Init();
	for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
	{
		MeshTopoData *ld = mMeshTopoData[ldID];
		Matrix3 tm = mMeshTopoData.GetNodeTM(t,ldID);

		for (int k = 0; k < ld->GetNumberFaces(); k++) 
		{
			if (ld->GetFaceSelected(k))
			{		// Grap the three points, xformed
				int pcount = 3;
				//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
				pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

				Point3 temp_point[4];
				for (int j=0; j<pcount; j++) 
				{
					int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
					Point3 p = ld->GetGeomVert(index) * tm * itm;//gverts.d[index].p * tm * itm;
					localBounds += p;

		//			if (fabs(p.x) > xmax) xmax = fabs(p.x);
		//			if (fabs(p.y) > ymax) ymax = fabs(p.y);
		//			if (fabs(p.z) > zmax) zmax = fabs(p.z);
				}
			}
		}
	}

	if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP))
		center = localBounds.Center() * tm;
	else if (fnGetMapMode() == CYLINDRICALMAP)
	{
		Point3 zvec = initialTM.GetRow(2);
		
//		center = center * tm;

		center = localBounds.Center() * tm - (zvec * 0.5f);
		

	}


	initialTM.SetRow(3,center);


	Matrix3 ptm(1), id(1);
	initialTM = initialTM ;
	SetXFormPacket tmpck(initialTM,ptm);
	tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);

	ResumeAnimate();

	if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == CYLINDRICALMAP) || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
		ApplyGizmo();

	theHold.Accept(GetString(IDS_MAPPING_FIT));
	fnGetGizmoTM();
	if (ip) ip->RedrawViews(ip->GetTime());

}
예제 #3
0
void UnwrapMod::fnAlignAndFit(int axis)
{



	//get our selection
	Box3 bounds;
	bounds.Init();
	//get the bounding box
	Point3 pnorm(0.0f,0.0f,0.0f);
	int ct = 0;
	TimeValue t = GetCOREInterface()->GetTime();
	for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
	{
		MeshTopoData *ld = mMeshTopoData[ldID];
		Matrix3 tm = mMeshTopoData.GetNodeTM(t,ldID);
		for (int k = 0; k < ld->GetNumberFaces(); k++) 
		{
			if (ld->GetFaceSelected(k))
			{
					// Grap the three points, xformed
				int pcount = 3;
					//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
				pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

				Point3 temp_point[4];
				for (int j=0; j<pcount; j++) 
				{
					int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
					bounds += ld->GetGeomVert(index) *tm;//gverts.d[index].p;
					if (j < 4)
						temp_point[j] = ld->GetGeomVert(index);//gverts.d[index].p;
				}
				pnorm += VectorTransform(Normalize(temp_point[1]-temp_point[0]^temp_point[2]-temp_point[1]),tm);
				ct++;
			}
		}	
	}

	if (ct == 0) return;

	theHold.Begin();
	SuspendAnimate();
	AnimateOff();

	pnorm = pnorm / (float) ct;
	Matrix3 tm(1);
	
	//if just a primary axis set the tm;
	Point3 center = bounds.Center();
		// build the scale
	Point3 scale(bounds.Width().x ,bounds.Width().y , bounds.Width().z);
	if (scale.x == 0.0f) scale.x = 1.0f;
	if (scale.y == 0.0f) scale.y = 1.0f;
 	if (scale.z == 0.0f) scale.z = 1.0f;
	
 	if (axis == 0) // x axi
	{

  		tm.SetRow(0,Point3(0.0f,-scale.y,0.0f));
		tm.SetRow(1,Point3(0.0f,0.0f,scale.z));
		tm.SetRow(2,Point3(scale.x,0.0f,0.0f));
		if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP)  || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
			tm.SetRow(3,center);
		else if (fnGetMapMode() == CYLINDRICALMAP)
		{
			center.x = bounds.pmin.x;
			tm.SetRow(3,center);
		}		

		Matrix3 ptm(1), id(1);
		tm = tm ;
		SetXFormPacket tmpck(tm,ptm);
		tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
	}
	else if (axis == 1) // y axi
	{
  		tm.SetRow(0,Point3(scale.x,0.0f,0.0f));
 		tm.SetRow(1,Point3(0.0f,0.0f,scale.z));
		tm.SetRow(2,Point3(0.0f,scale.y,0.0f));
		if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP)|| (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
			tm.SetRow(3,center);
		else if (fnGetMapMode() == CYLINDRICALMAP)
		{
			center.y = bounds.pmin.y;
			tm.SetRow(3,center);
		}
		

		Matrix3 ptm(1), id(1);
		tm = tm;
		SetXFormPacket tmpck(tm,ptm);
		tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
	}
	else if (axis == 2) //z axi
	{
		tm.SetRow(0,Point3(scale.x,0.0f,0.0f));
		tm.SetRow(1,Point3(0.0f,scale.y,0.0f));
		tm.SetRow(2,Point3(0.0f,0.0f,scale.z));
		if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP)|| (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
			tm.SetRow(3,center);
		else if (fnGetMapMode() == CYLINDRICALMAP)
		{
			center.z = bounds.pmin.z;
			tm.SetRow(3,center);
		}
		

		Matrix3 ptm(1), id(1);
		tm = tm;
		SetXFormPacket tmpck(tm,ptm);
		tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
	}
	else if (axis == 3) // normal
	{
		int numberOfSelectionGroups = 0;
		for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
		{
			MeshTopoData *ld = mMeshTopoData[ldID];
			if (ld->GetFaceSelection().NumberSet())
				numberOfSelectionGroups++;
		}
		if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP) || (numberOfSelectionGroups > 1))
		{
			//get our tm
			Matrix3 tm;
			UnwrapMatrixFromNormal(pnorm,tm);
 			Matrix3 itm = Inverse(tm);
			//find our x and y scale
			float xmax = 0.0f;
			float ymax = 0.0f;
			float zmax = 0.0f;
			Box3 localBounds;
			localBounds.Init();
			for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
			{
				MeshTopoData *ld = mMeshTopoData[ldID];
				Matrix3 tm = mMeshTopoData.GetNodeTM(t,ldID);
				for (int k = 0; k < ld->GetNumberFaces(); k++) 
				{
					if (ld->GetFaceSelected(k))
					{
							// Grap the three points, xformed
						int pcount = 3;
							//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
						pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

						Point3 temp_point[4];
						for (int j=0; j<pcount; j++) 
						{
							int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
							Point3 p = ld->GetGeomVert(index) * tm * itm;//gverts.d[index].p * itm;
							localBounds += p;
						}
					}
				}
			}

//			center = localBounds.Center();
			xmax = localBounds.pmax.x - localBounds.pmin.x;
			ymax = localBounds.pmax.y - localBounds.pmin.y;
			zmax = localBounds.pmax.z - localBounds.pmin.z;

			if (xmax < 0.001f)
				xmax = 1.0f;
			if (ymax < 0.001f)
				ymax = 1.0f;
			if (zmax < 0.001f)
				zmax = 1.0f;

			Point3 vec;
			vec = Normalize(tm.GetRow(0)) * xmax;
			tm.SetRow(0,vec);

			vec = Normalize(tm.GetRow(1)) * ymax;
			tm.SetRow(1,vec);

			vec = Normalize(tm.GetRow(2)) * zmax;
			tm.SetRow(2,vec);


			tm.SetRow(3,center);
			

			Matrix3 ptm(1), id(1);
			tm = tm ;
			SetXFormPacket tmpck(tm,ptm);
			tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
		}		
		else if ((fnGetMapMode() == CYLINDRICALMAP) || (fnGetMapMode() == SPHERICALMAP)|| (fnGetMapMode() == BOXMAP))
		{

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


				//get our first 2 rings
				Tab<int> openEdges;
				Tab<int> startRing;
				Tab<int> endRing;

				MeshTopoData *ld =  mMeshTopoData[ldID];

				//skip any local data that has no selections
				if (ld->GetFaceSelection().NumberSet() == 0)
					continue;

				Matrix3 nodeTM = mMeshTopoData.GetNodeTM(t,ldID);

				for (int i = 0; i < ld->GetNumberGeomEdges(); i++)//TVMaps.gePtrList.Count(); i++)
				{
					int numberSelectedFaces = 0;
					int ct = ld->GetGeomEdgeNumberOfConnectedFaces(i);//TVMaps.gePtrList[i]->faceList.Count();
					for (int j = 0; j < ct; j++)
					{
						int faceIndex = ld->GetGeomEdgeConnectedFace(i,j);//TVMaps.gePtrList[i]->faceList[j];
						if (ld->GetFaceSelected(faceIndex))//fsel[faceIndex])
							numberSelectedFaces++;
					}
					if (numberSelectedFaces == 1)
					{
						openEdges.Append(1,&i,1000);
						
					}
				}

				GetOpenEdges(ld,openEdges, startRing);
				GetOpenEdges(ld,openEdges, endRing);
				Point3 zVec = pnorm;

				Point3 centerS(0.0f,0.0f,0.0f), centerE;
				if ((startRing.Count() != 0) && (endRing.Count() != 0))
				{
					//get the center start
					Box3 BoundsS, BoundsE;
					BoundsS.Init();
					BoundsE.Init();

					//get the center end
					for (int i = 0; i < startRing.Count(); i++)
					{
						int eIndex = startRing[i];
						int a = ld->GetGeomEdgeVert(eIndex,0);//TVMaps.gePtrList[eIndex]->a;
						int b = ld->GetGeomEdgeVert(eIndex,1);//TVMaps.gePtrList[eIndex]->b;

						BoundsS += ld->GetGeomVert(a) * nodeTM;//TVMaps.geomPoints[a];
						BoundsS += ld->GetGeomVert(b) * nodeTM;//TVMaps.geomPoints[b];
					}


					for (int i = 0; i < endRing.Count(); i++)
					{
						int eIndex = endRing[i];
						int a = ld->GetGeomEdgeVert(eIndex,0);//TVMaps.gePtrList[eIndex]->a;
						int b = ld->GetGeomEdgeVert(eIndex,1);//TVMaps.gePtrList[eIndex]->b;

						BoundsE += ld->GetGeomVert(a) * nodeTM;//TVMaps.geomPoints[a];
						BoundsE += ld->GetGeomVert(b) * nodeTM;//TVMaps.geomPoints[b];
					}

					
					centerS = BoundsS.Center();
					centerE = BoundsE.Center();
					//create the vec
					zVec = centerE - centerS;

				}
				else if ((startRing.Count() != 0) && (endRing.Count() == 0))
				{
					//get the center start
					Box3 BoundsS;
					BoundsS.Init();
					

					//get the center end
					for (int i = 0; i < startRing.Count(); i++)
					{
						int eIndex = startRing[i];
						int a =  ld->GetGeomEdgeVert(eIndex,0);//TVMaps.gePtrList[eIndex]->a;
						int b =  ld->GetGeomEdgeVert(eIndex,1);//TVMaps.gePtrList[eIndex]->b;

						BoundsS += ld->GetGeomVert(a) * nodeTM;//TVMaps.geomPoints[a];
						BoundsS += ld->GetGeomVert(b) * nodeTM;//TVMaps.geomPoints[b];
					}

					centerS = BoundsS.Center();
					

					int farthestPoint= -1;
					Point3 fp;
					float farthestDist= 0.0f;
					for (int k=0; k < ld->GetNumberFaces(); k++) 
					{
						if (ld->GetFaceSelected(k))
						{
								// Grap the three points, xformed
							int pcount = 3;
								//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
							pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

							
							for (int j=0; j<pcount; j++) 
							{
								int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
								
								Point3 p = ld->GetGeomVert(index)* nodeTM;//gverts.d[index].p;
								float d = LengthSquared(p-centerS);
								if ((d > farthestDist) || (farthestPoint == -1))
								{
									farthestDist = d;
									farthestPoint = index;
									fp = p;
								}							
							}
						}
					}

					
					
					centerE = fp;
					//create the vec
					zVec = centerE - centerS;

				}
				else
				{
					zVec = Point3(0.0f,0.0f,1.0f);
				}


				//get our tm
				Matrix3 tm;
				UnwrapMatrixFromNormal(zVec,tm);
				tm.SetRow(3,centerS);
 				Matrix3 itm = Inverse(tm);
				//find our x and y scale
				float xmax = 0.0f;
				float ymax = 0.0f;
				float zmax = 0.0f;
				Box3 localBounds;
				localBounds.Init();
				for (int k = 0; k < ld->GetNumberFaces(); k++)//gfaces.Count(); k++) 
				{
					if (ld->GetFaceSelected(k))
					{
							// Grap the three points, xformed
						int pcount = 3;
							//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
						pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

						Point3 temp_point[4];
						for (int j=0; j<pcount; j++) 
						{
							int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
							Point3 p = ld->GetGeomVert(index) * nodeTM * itm;//gverts.d[index].p * itm;
							localBounds += p;
						}
					}
				}

				center = localBounds.Center() * tm;

				if (fnGetMapMode() == CYLINDRICALMAP)
				{
					if ((startRing.Count() == 0) && (endRing.Count() == 0))
					{
						centerS = center;
						centerS.z = localBounds.pmin.z;					
					}
					else
					{

						centerS = centerS * itm;
						centerS.z = localBounds.pmin.z;
						centerS = centerS * tm;
					}
				}
				else if ((fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
				{
					centerS = center;
				}

				Point3 bc = localBounds.Center();
				bc.z = localBounds.pmin.z;
				bc = bc * tm;

				xmax = localBounds.pmax.x - localBounds.pmin.x;
				ymax = localBounds.pmax.y - localBounds.pmin.y;
				zmax = localBounds.pmax.z - localBounds.pmin.z;

				Point3 vec;
				vec = Normalize(tm.GetRow(0)) * xmax;
				tm.SetRow(0,vec);

				vec = Normalize(tm.GetRow(1)) * ymax;
				tm.SetRow(1,vec);

				vec = Normalize(tm.GetRow(2)) * zmax;
				tm.SetRow(2,vec);


				
				tm.SetRow(3,centerS);
				

				Matrix3 ptm(1), id(1);
				tm = tm;
				SetXFormPacket tmpck(tm,ptm);
				tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
			}
			
		}
	}
	ResumeAnimate();

	if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == CYLINDRICALMAP) || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
		ApplyGizmo();

	theHold.Accept(GetString(IDS_MAPPING_ALIGN));

	fnGetGizmoTM();

	if (ip) ip->RedrawViews(ip->GetTime());

}
예제 #4
0
void UnwrapMod::fnGizmoReset()
{


	
	theHold.Begin();
	SuspendAnimate();
	AnimateOff();
	TimeValue t = GetCOREInterface()->GetTime();



	
	//get our selection
	Box3 bounds;
	bounds.Init();
	//get the bounding box

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

		Matrix3 tm = mMeshTopoData.GetNodeTM(t,ldID);

		for (int k = 0; k < ld->GetNumberFaces(); k++)//gfaces.Count(); k++) 
		{
			if (ld->GetFaceSelected(k))
			{
					// Grap the three points, xformed
				int pcount = 3;
					//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
				pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

				Point3 temp_point[4];
				for (int j=0; j<pcount; j++) 
				{
					int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];
					bounds += ld->GetGeomVert(index) * tm;//gverts.d[index].p;
				}
			}
		}	

	}
	
	Matrix3 tm(1);
	
	//if just a primary axis set the tm;
	Point3 center = bounds.Center();
		// build the scale
 	Point3 scale(bounds.Width().x ,bounds.Width().y , bounds.Width().z);
	if (scale.x == 0.0f) scale.x = 1.0f;
	if (scale.y == 0.0f) scale.y = 1.0f;
 	if (scale.z == 0.0f) scale.z = 1.0f;
	float scl = scale.x;
	if (scale.y > scl) scl = scale.y;
	if (scale.z > scl) scl = scale.z;
	scale.x = scl;
	scale.y = scl;
	scale.z = scl;
	
	tm.SetRow(0,Point3(scale.x,0.0f,0.0f));
	tm.SetRow(1,Point3(0.0f,scale.y,0.0f));
	tm.SetRow(2,Point3(0.0f,0.0f,scale.z));
	if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP)|| (fnGetMapMode() == SPHERICALMAP))
		tm.SetRow(3,center);
	else if (fnGetMapMode() == CYLINDRICALMAP)
	{
		center.z = bounds.pmin.z;
		tm.SetRow(3,center);
	}
		

	Matrix3 ptm(1), id(1);
	tm = tm ;
	SetXFormPacket tmpck(tm,ptm);
	tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE);
	ResumeAnimate();

	if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == CYLINDRICALMAP) || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP))
		ApplyGizmo();


	theHold.Accept(GetString(IDS_MAPPING_RESET));
	fnGetGizmoTM();
	if (ip) ip->RedrawViews(ip->GetTime());

}
예제 #5
0
void UnwrapMod::ApplyGizmo()
{

	if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP) ||
		(fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == CYLINDRICALMAP))
	{
		ApplyGizmoPrivate();
	}
	else
	{
  		theHold.Begin();
		//compute the center
			//get our normal list
		for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
		{
			MeshTopoData *ld = mMeshTopoData[ldID];
			ld->HoldFaceSel();
		}

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

			Tab<Point3> fnorms;
			fnorms.SetCount(ld->GetNumberFaces());
			for (int k=0; k< fnorms.Count(); k++) 
				fnorms[k] = Point3(0.0f,0.0f,0.0f);
				
			//get our projection normal
			Point3 projectionNorm(0.0f,0.0f,0.0f);

			//build normals
			for (int k = 0; k < fnorms.Count(); k++) 
			{
				if (ld->GetFaceSelected(k))
				{
							// Grap the three points, xformed
					int pcount = 3;
					//				if (gfaces[k].flags & FLAG_QUAD) pcount = 4;
					pcount = ld->GetFaceDegree(k);//gfaces[k]->count;

					Point3 temp_point[4];
					for (int j=0; j<pcount; j++) 
					{
						int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j];							
						if (j < 4)
							temp_point[j] = ld->GetGeomVert(index);//gverts.d[index].p;
					}
					
					fnorms[k] = Normalize(temp_point[1]-temp_point[0]^temp_point[2]-temp_point[1]);
				}
			}
				
			BitArray front,back,left,right,top,bottom;
			front.SetSize(ld->GetNumberFaces());
			front.ClearAll();
			back = front;
			left = front;
			right = front;
			top = front;
			bottom = front;

			Tab<Point3> norms;

			Matrix3 gtm(1);
			TimeValue t = 0;
			if (ip) t = ip->GetTime();
			if (tmControl)
				tmControl->GetValue(t,&gtm,FOREVER,CTRL_RELATIVE);

			norms.SetCount(6);
			for (int i = 0; i < 3; i++)
			{
				Point3 v = gtm.GetRow(i);
				norms[i*2] = Normalize(v);
				norms[i*2+1] = norms[i*2] * -1.0f;
			}
				
			for (int k=0; k< ld->GetNumberFaces(); k++) 
			{
				if (ld->GetFaceSelected(k))
				{
					int closestFace = -1;
					float closestAngle = -10.0f;
					for (int j = 0; j < 6; j++)
					{
						float dot = DotProd(norms[j],fnorms[k]);
						if (dot > closestAngle)
						{
							closestAngle = dot;
							closestFace = j;
						}
					}
					if (closestFace == 0)
						front.Set(k,TRUE);
					else if (closestFace == 1)
						back.Set(k,TRUE);
					else if (closestFace == 2)
						left.Set(k,TRUE);
					else if (closestFace == 3)
						right.Set(k,TRUE);
					else if (closestFace == 4)
						top.Set(k,TRUE);
					else if (closestFace == 5)
						bottom.Set(k,TRUE);
				}
			}


			gtm.IdentityMatrix();
			if (tmControl)
				tmControl->GetValue(t,&gtm,FOREVER,CTRL_RELATIVE);

			Point3 xvec,yvec,zvec;
			xvec = gtm.GetRow(0);
			yvec = gtm.GetRow(1);
			zvec = gtm.GetRow(2);
  			Point3 center = gtm.GetRow(3);


			for (int k = 0; k < 6; k++)
			{

				Matrix3 tm(1);
				if (k == 0)
				{
					tm.SetRow(0,yvec);
					tm.SetRow(1,zvec);
					tm.SetRow(2,xvec);
					ld->SetFaceSelection(front);
				}
				else if (k == 1)
				{
					tm.SetRow(0,yvec);
					tm.SetRow(1,zvec);
					tm.SetRow(2,(xvec*-1.0f));

					ld->SetFaceSelection(back);
				}
				else if (k == 2)
				{
					tm.SetRow(0,xvec);
					tm.SetRow(1,zvec);
					tm.SetRow(2,yvec);

					ld->SetFaceSelection(left);
				}
				else if (k == 3)
				{
					tm.SetRow(0,xvec);
					tm.SetRow(1,zvec);
					tm.SetRow(2,(yvec *-1.0f));

					ld->SetFaceSelection(right);
				}
				else if (k == 4)
				{
					tm.SetRow(0,xvec);
					tm.SetRow(1,yvec);
					tm.SetRow(2,zvec);

					ld->SetFaceSelection(top);
				}
				else if (k == 5)
				{
					tm.SetRow(0,xvec);
					tm.SetRow(1,yvec);
					tm.SetRow(2,(zvec*-1.0f));

					ld->SetFaceSelection(bottom);
				}

				

				tm.SetRow(3,center);

				if (!fnGetNormalizeMap())
				{
					for (int i = 0; i < 3; i++)
					{
						Point3 vec = tm.GetRow(i);
						vec = Normalize(vec);
						tm.SetRow(i,vec);
					}
				}

				tm = mMeshTopoData.GetNodeTM(t,ldID) * Inverse(tm);
				ld->ApplyMap(fnGetMapMode(), fnGetNormalizeMap(), tm, this);				
			}
			ld->RestoreFaceSel();
		}

		theHold.Accept(GetString(IDS_PW_PLANARMAP));
		
	}

}
예제 #6
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
		}
	}
예제 #7
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++;
		}
	}

}
예제 #8
0
void	UnwrapMod::fnPaste(BOOL rotate)
	{
	//check for type

	TimeValue t = GetCOREInterface()->GetTime();
	theHold.Begin();
	HoldPointsAndFaces();

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


//check faces if just one selected normal paste with rotates
//or if all faces where selected
//or if first paste

//hold the points and faces


		BitArray holdFaceSel(ld->GetFaceSelection());

		BitArray subFaceSel;
		if ( ip && (ip->GetSubObjectLevel() == 0) )
			{
//convert our current selection into faces			
			if (fnGetTVSubMode() == TVVERTMODE)
				ld->GetFaceSelFromVert(subFaceSel,FALSE);
			else if (fnGetTVSubMode() == TVEDGEMODE)
				{
				BitArray tempVSel;
				ld->GetVertSelFromEdge(tempVSel);
				BitArray vsel = ld->GetTVVertSelection();
				BitArray holdVSel(vsel);
				ld->SetTVVertSelection(tempVSel);//vsel = tempVSel;
				ld->GetFaceSelFromVert(subFaceSel,FALSE);
				ld->SetTVVertSelection(holdVSel);//vsel = holdVSel;

				}
			else if (fnGetTVSubMode() == TVFACEMODE)
				{
				subFaceSel = ld->GetFaceSelection();//.SetSize(fsel.GetSize());
				//subFaceSel = fsel;
				}
			}
		else
			{
			if (fnGetTVSubMode() == TVFACEMODE)
				{
				subFaceSel = ld->GetFaceSelection();//.SetSize(fsel.GetSize());
				//subFaceSel = fsel;
				}

			}

		if ( (copyPasteBuffer.copyType == 0) || (copyPasteBuffer.copyType == 1) || (copyPasteBuffer.iRotate==0))
			{
			int copyIndex = 0;
			Tab<int> vertexLookUpList;

			vertexLookUpList.SetCount(copyPasteBuffer.tVertData.Count());

			BitArray faceSel = ld->GetFaceSelection();

			for (int i =0; i < vertexLookUpList.Count(); i++)
				vertexLookUpList[i] = -1;
			if (copyPasteBuffer.copyType == 1)
				copyPasteBuffer.iRotate = 0;
			else 
				{
				if (copyPasteBuffer.lastSel.GetSize() == faceSel.GetSize())
					{
					if (copyPasteBuffer.lastSel == faceSel) 
						{

						if (rotate)
							{
							copyPasteBuffer.iRotate++;
							}
						else copyPasteBuffer.iRotate = 0;

						
						}
					}
				}
			if (copyPasteBuffer.copyType == 2) copyPasteBuffer.iRotate = 0;
			copyPasteBuffer.lastSel = faceSel;

//loop through selected faces
			for (int i =0; i < faceSel.GetSize(); i++)
				{
				if (faceSel[i])
					{
//make sure selected faces count = buffer face
					if (( i < ld->GetNumberFaces()/*TVMaps.f.Count()*/) && (copyIndex < copyPasteBuffer.faceData.Count()))
						{
						int degree = ld->GetFaceDegree(i);
						if (/*TVMaps.f[i]->count*/ degree == copyPasteBuffer.faceData[copyIndex]->count)
							{
//if so	set the face data indices as the same
							for (int j = 0; j < degree/*TVMaps.f[i]->count*/; j++)
								{
							//index into the texture vertlist
							
								int vid = (j + copyPasteBuffer.iRotate)%degree;//TVMaps.f[i]->count;
								int vertexIndex = copyPasteBuffer.faceData[copyIndex]->t[vid];

								if (vertexLookUpList[vertexIndex] == -1)
									{
									Point3 p = copyPasteBuffer.tVertData[vertexIndex];
									ld->AddTVVert(t, p, i, j, this,FALSE);//ld->AddPoint(p, i, j,FALSE);
									vertexLookUpList[vertexIndex] = ld->GetFaceTVVert(i,j);//TVMaps.f[i]->t[j];
									}
								else 
									 ld->SetFaceTVVert(i,j,vertexLookUpList[vertexIndex]);//TVMaps.f[i]->t[j] = vertexLookUpList[vertexIndex];

								if ((ld->GetFaceHasVectors(i)/*TVMaps.f[i]->vecs*/) && (copyPasteBuffer.faceData[copyIndex]->vecs) && (j < 4))
									{
									int hid = (j*2 + (copyPasteBuffer.iRotate*2))%(/*TVMaps.f[i]->count*/degree*2);
									int handleIndex = copyPasteBuffer.faceData[copyIndex]->vecs->handles[hid];
									if ((handleIndex >= 0) && (vertexLookUpList[handleIndex] == -1))
										{
										Point3 p = copyPasteBuffer.tVertData[handleIndex];
										ld->AddTVHandle(t,p, i, j*2,this,FALSE);
										vertexLookUpList[handleIndex] = ld->GetFaceTVHandle(i,j*2);// TVMaps.f[i]->vecs->handles[j*2];
										}
									else 
										ld->SetFaceTVHandle(i,j*2,vertexLookUpList[handleIndex]);//TVMaps.f[i]->vecs->handles[j*2] = vertexLookUpList[handleIndex];
	
									hid = (j*2 + (copyPasteBuffer.iRotate*2))%(degree/*TVMaps.f[i]->count*/*2)+1;
									handleIndex = copyPasteBuffer.faceData[copyIndex]->vecs->handles[hid];
									if ((handleIndex >= 0) && (vertexLookUpList[handleIndex] == -1))
										{
										Point3 p = copyPasteBuffer.tVertData[handleIndex];
										ld->AddTVHandle(t,p, i, j*2+1,this,FALSE);
										vertexLookUpList[handleIndex] = ld->GetFaceTVHandle(i,j*2+1);//TVMaps.f[i]->vecs->handles[j*2+1];
										}
									else 
										ld->SetFaceTVHandle(i,j*2+1,vertexLookUpList[handleIndex]);//TVMaps.f[i]->vecs->handles[j*2+1] = vertexLookUpList[handleIndex];
	
									int iid = (j + (copyPasteBuffer.iRotate))%degree;//(TVMaps.f[i]->count);
									int interiorIndex = copyPasteBuffer.faceData[copyIndex]->vecs->interiors[iid];
									if ((interiorIndex >= 0) && (vertexLookUpList[interiorIndex] == -1))
										{
										Point3 p = copyPasteBuffer.tVertData[interiorIndex];
										ld->AddTVInterior(t,p, i, j,this,FALSE);
										vertexLookUpList[interiorIndex] = ld->GetFaceTVInterior(i,j);//TVMaps.f[i]->vecs->handles[j];
										}
									else 
										ld->SetFaceTVInterior(i,j,vertexLookUpList[interiorIndex]);//TVMaps.f[i]->vecs->interiors[j] = vertexLookUpList[interiorIndex];
									}
								}
							copyIndex++;
							if (copyIndex >= copyPasteBuffer.faceData.Count()) copyIndex = 0;
							}
						}	
					}

				}

			}
		
		ld->SetTVEdgeInvalid();//RebuildEdges();

		if ( ip && (ip->GetSubObjectLevel() == 0) )
			{
			if (fnGetTVSubMode() == TVVERTMODE)
				{
				BitArray fsel = ld->GetFaceSelection();
				BitArray vsel = ld->GetTVVertSelection();
				BitArray holdFSel(fsel);
				fsel = subFaceSel;
				ld->GetVertSelFromFace(vsel);
				ld->SetTVVertSelection(vsel);
				ld->SetFaceSelection(holdFSel);//fsel = holdFSel;
				}
			else if (fnGetTVSubMode() == TVEDGEMODE)
				{
				BitArray fsel = ld->GetFaceSelection();
				BitArray esel = ld->GetTVEdgeSelection();
				BitArray holdFSel(fsel);
				fsel = subFaceSel;
				ld->GetVertSelFromFace(fsel);
				ld->SetFaceSelection(fsel);//
				ld->GetEdgeSelFromVert(esel,FALSE);
				ld->SetTVEdgeSelection(esel);
				ld->SetFaceSelection(holdFSel);//fsel = holdFSel;
				}
			else if (fnGetTVSubMode() == TVFACEMODE)
				{				
				ld->SetFaceSelection(subFaceSel);//fsel = subFaceSel;
				}

			}
		else
			{
//			md->faceSel = holdFaceSel;
			ld->SetFaceSelection(subFaceSel);
/*
			if (fnGetTVSubMode() == TVFACEMODE)
				{
				ld->SetFaceSelection(subFaceSel);//fsel = subFaceSel;
				}
*/
			}

		}
		CleanUpDeadVertices();
		theHold.Accept(GetString(IDS_PW_PASTE));

		NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE);
		InvalidateView();
		GetCOREInterface()->RedrawViews(GetCOREInterface()->GetTime());		

	}
예제 #9
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);

}
예제 #10
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();

}