예제 #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
파일: mesh.cpp 프로젝트: 2asoft/xray
void UnwrapMod::GetFaceSelectionFromMesh(ObjectState *os, ModContext &mc, TimeValue t)
	{
	TriObject *tobj = (TriObject*)os->obj;
	MeshTopoData *d  = (MeshTopoData*)mc.localData;
	if (d)
		{
		d->SetFaceSel(tobj->GetMesh().faceSel, this, t);
		UpdateFaceSelection(d->faceSel);
		}
	}
예제 #3
0
void TweakMode::ExitMode()
{

	mod->GetUIManager()->UpdateCheckButtons();

	for (int ldID = 0; ldID < mod->GetMeshTopoDataCount(); ldID++)
	{
		MeshTopoData *ld = mod->GetMeshTopoData(ldID);
		ld->PostIntersect();
	}
}
예제 #4
0
파일: mesh.cpp 프로젝트: 2asoft/xray
void UnwrapMod::CopySelectionMesh(ObjectState *os, ModContext &mc, int CurrentChannel, TimeValue t)
	{	

		objType = IS_MESH;
		TriObject *tobj = (TriObject*)os->obj;
		MeshTopoData *d  = (MeshTopoData*)mc.localData;
		if (!d) 
			{
			mc.localData = d = new MeshTopoData(tobj->GetMesh());
			d->SetFaceSel(tobj->GetMesh().faceSel, this, t);
			UpdateFaceSelection(d->faceSel);
			

			}
		if ( ((editMod==this) && (!d->GetMesh())) || (updateCache))
			{
			d->SetCache(tobj->GetMesh());
			d->SetFaceSel(tobj->GetMesh().faceSel, this, t);
			updateCache = FALSE;
			UpdateFaceSelection(d->faceSel);
			SyncTVToGeomSelection(d);

			hiddenPolygons.SetSize(tobj->GetMesh().getNumFaces());
			hiddenPolygons.ClearAll();
			for (int i = 0; i < tobj->GetMesh().getNumFaces(); i++)
				{
				if (tobj->GetMesh().faces[i].Hidden())
					hiddenPolygons.Set(i,TRUE);
				}
			}

		BitArray faceSel = d->faceSel;


		faceSel.SetSize(tobj->GetMesh().getNumFaces(),TRUE);

		if ( (ip && (ip->GetSubObjectLevel() > 0) ))
			{

			tobj->GetMesh().faceSel = faceSel;

			if (showVerts)
				{
//select verts based on the current tverts;
				BitArray vertSel;
				vertSel.SetSize(tobj->GetMesh().getNumVerts(),TRUE);
				vertSel.ClearAll();
				for(int sv = 0; sv < TVMaps.f.Count();sv++)
					{
					if (!(TVMaps.f[sv]->flags & FLAG_DEAD))
						{
						int pcount = 3;
//						if (TVMaps.f[sv].flags & FLAG_QUAD) pcount = 4;
						pcount = TVMaps.f[sv]->count;
						for (int j = 0; j < pcount ; j++)
							{
							int index = TVMaps.f[sv]->t[j];
//6-29--99 watje
							if ((index < vsel.GetSize()) && (vsel[index] ==1) && (sv<tobj->GetMesh().numFaces))
//							if (vsel[index] ==1)
								{
								int findex = tobj->GetMesh().faces[sv].v[j];
//6-29--99 watje
								if ((findex < vertSel.GetSize()) && (findex >=0))
									vertSel.Set(findex,1);
								}
							}
						}
					}
				tobj->GetMesh().vertSel = vertSel;
				tobj->GetMesh().SetDispFlag(DISP_SELFACES|DISP_VERTTICKS|DISP_SELVERTS);
//done++;
				}
			else
				{
				tobj->GetMesh().SetDispFlag(DISP_SELFACES);
				}

//UNFOLD STUFF
			Face *faces = tobj->GetMesh().faces;
			for (int i =0; i < tobj->GetMesh().getNumFaces(); i++)
				{
				if ( (i < hiddenPolygons.GetSize()) && (hiddenPolygons[i]) ) 
					faces[i].Hide();
				else faces[i].Show();
				}

			}

		
		if (!tmControl || (flags&CONTROL_OP) || (flags&CONTROL_INITPARAMS)) 
			InitControl(t);


//if planar mode build vert and face list

		if ( (ip && (ip->GetSubObjectLevel() == 1) ))
			{
			MeshUpdateGData(&tobj->GetMesh(),faceSel);
	
			}

	}
예제 #5
0
int TweakMouseProc::proc(
									HWND hwnd, 
									int msg, 
									int point, 
									int flags, 
									IPoint2 m )
{
	int res = TRUE;

	ViewExp& vpt = iObjParams->GetViewExp(hwnd);   
	
	if ( ! vpt.IsAlive() )
	{
		// why are we here
		DbgAssert(!_T("Invalid viewport!"));
		return FALSE;
	}
	

	static IPoint2 cancelPoints[3];
	static HWND cancelHWND;


	switch ( msg ) 
	{
	case MOUSE_PROPCLICK:
		//reset start point

//kill the command mode
		SetCursor(LoadCursor(NULL,IDC_ARROW));
		GetCOREInterface()->SetStdCommandMode(CID_OBJSELECT);
		mHitLD = NULL;
		break;

	case MOUSE_ABORT:
		{
			theHold.Cancel();

			if (mHitLD)
			{
				mHitLD->SetTVVert(GetCOREInterface()->GetTime(),mHitTVVert,mSourceUVW,mod);

				mod->NotifyDependents(FOREVER, PART_TEXMAP, REFMSG_CHANGE);
				mod->InvalidateView();
				if (mod->ip) 
					mod->ip->RedrawViews(mod->ip->GetTime());
			}
			break;
		}
	case MOUSE_POINT:
		{
//see if we hit a point
			if (point == 0)
			{		
				theHold.Begin();
				mod->HoldPoints();

				mHitLD = HitTest(vpt, m, mHitVert);
				if (mHitLD != NULL)
				{
					float at = 0;
					Ray r;
					vpt.MapScreenToWorldRay ((float) m.x, (float) m.y, r);
					TimeValue t = GetCOREInterface()->GetTime();
					Matrix3 tm = mod->GetMeshTopoDataNode(mHitLDIndex)->GetObjectTM(t);
					Matrix3 itm = Inverse(tm);

					r.p = r.p * itm;
					r.dir = VectorTransform(r.dir,itm);

					mHitLD->Intersect(r,true,false, at, mBary, mHitFace);
					if (mHitFace != -1)
					{
						int deg = mHitLD->GetFaceDegree(mHitFace);
						for (int j = 0; j < deg; j++)
						{
							if (mHitVert == mHitLD->GetFaceGeomVert(mHitFace,j))
							{
								mHitTVVert = mHitLD->GetFaceTVVert(mHitFace,j);
								mSourceUVW =  mHitLD->GetTVVert(mHitTVVert);
								int offset1 = j;
								int offset2 = j+1;
								if (j == 0)
								{
									offset1 = 1;
									offset2 = 2;
								}
								else if (j == deg-1)
								{
									offset1 = deg-1;
									offset2 = deg-2;			
								}
								mHitP[0] = mHitLD->GetGeomVert(mHitLD->GetFaceGeomVert(mHitFace,0));
								mHitP[1] = mHitLD->GetGeomVert(mHitLD->GetFaceGeomVert(mHitFace,offset1));
								mHitP[2] = mHitLD->GetGeomVert(mHitLD->GetFaceGeomVert(mHitFace,offset2));								

								mHitUVW[0] = mHitLD->GetTVVert(mHitLD->GetFaceTVVert(mHitFace,0));
								mHitUVW[1] = mHitLD->GetTVVert(mHitLD->GetFaceTVVert(mHitFace,offset1));
								mHitUVW[2] = mHitLD->GetTVVert(mHitLD->GetFaceTVVert(mHitFace,offset2));								

							}															
						}
					}
					else
					{
						mHitLD->Intersect(r,true,false, at, mBary, mHitFace);
						mHitLD = NULL;
					}
				}
			}
			else
			{
				//accept the undo
				if (mHitLD)
				{
					if (flags & MOUSE_SHIFT)
					{
						AverageUVW();
					}
					else
					{
						ComputeNewUVW(vpt, m);
					}	

					mHitLD = NULL;
					TSTR mstr = mod->GetMacroStr(_T("modifiers[#unwrap_uvw].unwrap.setVertexPositionByNode"));
					macroRecorder->FunctionCall(mstr, 4, 0,	
								mr_time,GetCOREInterface()->GetTime(),
								mr_int,mHitTVVert+1,
								mr_point3, mFinalUVW,
								mr_reftarg,	mod->GetMeshTopoDataNode(mHitLDIndex)	);						
				}
				theHold.Accept(GetString (IDS_DS_MOVE2));
			}

		break;
		}
	case MOUSE_MOVE:
		{
//if we hit a point get the transform and compute the uv offset
			if (mHitLD)
			{
				if (flags & MOUSE_SHIFT)
				{
					AverageUVW();
				}
				else
				{
					ComputeNewUVW(vpt, m);
				}				
			}
		break;
		}		
	case MOUSE_FREEMOVE:
		{
	
		//see if hit and set cursor
		//hit test point
		int index = -1;
		
		float at = 0;
		Ray r;
		vpt.MapScreenToWorldRay ((float) m.x, (float) m.y, r);
		TimeValue t = GetCOREInterface()->GetTime();
		BOOL hitFace = FALSE;

		for (int ldID = 0; ldID < mod->GetMeshTopoDataCount(); ldID++)
		{
			Matrix3 tm = mod->GetMeshTopoDataNode(ldID)->GetObjectTM(t);
			Matrix3 itm = Inverse(tm);

			r.p = r.p * itm;
			r.dir = VectorTransform(r.dir,itm);

			MeshTopoData *ld = mod->GetMeshTopoData(ldID);
			Point3 bry;
			int hit = -1;
			if (ld)
			{
				if (ld->Intersect(r,true,false, at, bry, hit))
					hitFace = TRUE;
			}
		}


		if ((HitTest(vpt, m, index)!= NULL) && hitFace)
			SetCursor(GetCOREInterface()->GetSysCursor(SYSCUR_SELECT));
		else SetCursor(LoadCursor(NULL,IDC_ARROW));
		
		break;
		}
	}


	return res;

}
예제 #6
0
unsigned __stdcall  CallRelaxThread(void *data)
{
	MaxSDK::Util::UseLanguagePackLocale();

	RelaxThreadData *threadData = (RelaxThreadData *) data;

	threadData->mLocalData.SetCount( threadData->mod->GetMeshTopoDataCount());
	for (int i = 0; i <  threadData->mod->GetMeshTopoDataCount(); i++)
		threadData->mLocalData[i] =  threadData->mod->GetMeshTopoData(i);

	threadData->mStarted = TRUE;

	DisableAccelerators();  



	BOOL rigSelected = FALSE;
	MeshTopoData *peltLD = threadData->mod->peltData.mBaseMeshTopoDataCurrent;
	if (threadData->mod->peltData.peltDialog.hWnd)
	{		
		if (peltLD)
		{
			for (int i = 0; i < threadData->mod->peltData.rigPoints.Count(); i++)
			{
				int index = threadData->mod->peltData.rigPoints[i].lookupIndex;
				if (peltLD->GetTVVertSelected(index))
					rigSelected = TRUE;
			}
		}
	}

	GetCOREInterface()->DisableSceneRedraw();
	//if we are not instanced we can just start up unwrap relax and go
	if ((threadData->mod->GetMeshTopoDataCount() == 1) && !rigSelected)
	{
		if (threadData->mType == 0)
			threadData->mod->fnRelaxByFaceAngle(threadData->mIterations,threadData->mStretch,threadData->mAmount,threadData->mBoundary,NULL);
		else if (threadData->mType == 1)
			threadData->mod->fnRelaxByEdgeAngle(threadData->mIterations,threadData->mStretch,threadData->mAmount,threadData->mBoundary,NULL);
		else if (threadData->mType == 2)
			threadData->mod->RelaxVerts2(threadData->mAmount,threadData->mIterations,threadData->mBoundary,threadData->mCorner,FALSE);
	}
	//if we have multiple instance it gets more complicated
	//since only the first relax instance will ever run
	else
	{
		BOOL done = FALSE;
		threadData->mIterations = 5;
		for (int ldID = 0; ldID < threadData->mLocalData.Count(); ldID++)
		{
			threadData->mLocalData[ldID]->SetUserCancel(FALSE);
		}
		while(!done)
		{
			for (int ldID = 0; ldID < threadData->mLocalData.Count(); ldID++)
			{
				if (threadData->mLocalData[ldID]->GetUserCancel())
					done = TRUE;
			}
			if (threadData->mType == 0)
				threadData->mod->fnRelaxByFaceAngle(threadData->mIterations,threadData->mStretch,threadData->mAmount,threadData->mBoundary,NULL);
			else if (threadData->mType == 1)
				threadData->mod->fnRelaxByEdgeAngle(threadData->mIterations,threadData->mStretch,threadData->mAmount,threadData->mBoundary,NULL);
			else if (threadData->mType == 2)
				threadData->mod->RelaxVerts2(threadData->mAmount,threadData->mIterations,threadData->mBoundary,threadData->mCorner,FALSE);

			if (rigSelected)
				threadData->mod->peltData.RelaxRig(threadData->mIterations,threadData->mAmount,threadData->mBoundary,threadData->mod);
		}
	}



	for (int ldID = 0; ldID < threadData->mod->GetMeshTopoDataCount(); ldID++)
	{
		threadData->mod->GetMeshTopoData(ldID)->SetUserCancel(FALSE);
	}


	GetCOREInterface()->EnableSceneRedraw();
	EnableAccelerators();   
	threadData->mStarted = FALSE;

	ICustButton *iButton = GetICustButton(GetDlgItem(threadData->mod->relaxHWND, IDC_RUN_BUTTON));
	if (iButton)
	{
		if (iButton->IsChecked())
		{
			iButton->SetText(GetString(IDS_SPLINEMAP_STARTRELAX));
			iButton->SetCheck(FALSE);
		}
		ReleaseICustButton(iButton);
	}

	_endthreadex(0);


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

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

}
예제 #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::ApplyGizmoPrivate(Matrix3 *defaultTM)
{
	BOOL wasHolding = FALSE;
 	if (theHold.Holding())
		wasHolding = TRUE;


	if (!theHold.Holding())
	{
		theHold.Begin();
	}
	HoldPointsAndFaces();	


	//add vertices to our internal vertex list filling in dead spots where appropriate

	//get align normal
	//get fit data


	Matrix3 gtm(1);
	TimeValue t = 0;
	if (ip) t = ip->GetTime();
	if (defaultTM)
		gtm = *defaultTM;
	else
	{
		if (tmControl)
		{
			
			gtm = GetMapGizmoMatrix(t);

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

		}

	}

	for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
	{
		MeshTopoData *ld = mMeshTopoData[ldID];
		Matrix3 tm(1);
		tm = mMeshTopoData.GetNodeTM(t,ldID)* Inverse(gtm);
		ld->ApplyMap(fnGetMapMode(), fnGetNormalizeMap(), tm, this);
		ld->SetTVEdgeInvalid();
		ld->BuildTVEdges();
		ld->BuildVertexClusterList();
		
	}


	if (!wasHolding)
	{
		theHold.Accept(GetString(IDS_PW_PLANARMAP));
	}

	RebuildEdges();
	theHold.Suspend();
	fnFaceToEdgeSelect();
	theHold.Resume();

//	ConvertFaceToEdgeSel();
//	TVMaps.edgesValid= FALSE;
	//update our views to show new faces

	InvalidateView();

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

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

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

	}
예제 #15
0
void UnwrapMod::fnFlattenMap(float angleThreshold, Tab<Point3*> *normalList, float spacing, BOOL normalize, int layoutType, BOOL rotateClusters, BOOL fillHoles)

{
	for (int i = 0; i < mMeshTopoData.Count(); i++)
	{
		mMeshTopoData[i]->HoldSelection();
	}



	BailStart();

	if (preventFlattening) return;
	/*
	if (TVMaps.f.Count() == 0) return;

	BitArray *polySel = fnGetSelectedPolygons();
	if (polySel == NULL) 
	return;
	*/

	theHold.Begin();
	HoldPointsAndFaces();   
	/*
	BitArray holdPolySel;
	holdPolySel.SetSize(polySel->GetSize());
	holdPolySel = *polySel;
	*/
	Point3 normal(0.0f,0.0f,1.0f);

	Tab<Point3> mapNormal;
	mapNormal.SetCount(normalList->Count());
	for (int i =0; i < mapNormal.Count(); i++)
	{
		mapNormal[i] = *(*normalList)[i];
	}

	BOOL noSelection = TRUE;
	for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
	{
		if (mMeshTopoData[ldID]->GetFaceSelection().NumberSet())
			noSelection = FALSE;
	}

	if (noSelection)
	{
		for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++)
		{
			BitArray fsel = mMeshTopoData[ldID]->GetFaceSelection();
			fsel.SetAll();
			mMeshTopoData[ldID]->SetFaceSelection(fsel);
		}
	}

	TSTR statusMessage;
	MeshTopoData::GroupBy groupBy = MeshTopoData::kFaceAngle;
	int v = 0;
	pblock->GetValue(unwrap_flattenby,0,v,FOREVER);
	if (v == 0)
		groupBy = MeshTopoData::kFaceAngle;
	else if (v == 2)
		groupBy = MeshTopoData::kMaterialID;
	else if (v == 1)
		groupBy = MeshTopoData::kSmoothingGroup;

	BOOL bContinue = BuildCluster( mapNormal, angleThreshold, TRUE,TRUE,groupBy);
	/*
	BitArray sel;
	sel.SetSize(TVMaps.f.Count());
	*/
	gBArea = 0.0f;

	int initialCluster = clusterList.Count();

	if (bContinue)
	{
		for (int i =0; i < clusterList.Count(); i++)
		{
			MeshTopoData *ld = clusterList[i]->ld;
			ld->ClearSelection(TVFACEMODE);//         sel.ClearAll();
			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;
			}

		}

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

			if (layoutType == 1)
				bContinue = LayoutClusters( spacing, rotateClusters, TRUE, fillHoles);
			else
			{
				if (flattenMax5)
					bContinue = LayoutClusters3( spacing, rotateClusters, fillHoles);
				else bContinue = LayoutClusters2( spacing, rotateClusters, fillHoles);

			}

			//normalize map to 0,0 to 1,1
			if ((bContinue) && (normalize))
			{
				NormalizeCluster(spacing);
			}
		}

	}

	CleanUpDeadVertices();
	if (bContinue)
	{
		theHold.Accept(GetString(IDS_PW_FLATTEN));

		theHold.Suspend();
		fnSyncTVSelection();
		theHold.Resume();

	}
	else
	{
		theHold.Cancel();
		//    theHold.SuperCancel();
	}

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


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

	for (int i = 0; i < mMeshTopoData.Count(); i++)
	{
		mMeshTopoData[i]->RestoreSelection();
	}


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


#ifdef DEBUGMODE 
	if (gDebugLevel >= 1)
	{
		int finalCluster = clusterList.Count();
		gEdgeHeight = 0.0f;
		gEdgeWidth = 0.0f;
		for (int i =0; i < clusterList.Count(); i++)
		{
			gEdgeHeight += clusterList[i]->h;
			gEdgeWidth += clusterList[i]->w;

		}

		ScriptPrint(_T("Surface Area %f bounds area %f  per used %f\n"),gSArea,gBArea,gSArea/gBArea); 
		ScriptPrint(_T("Edge Height %f Edge Width %f\n"),gEdgeHeight,gEdgeWidth); 
		ScriptPrint(_T("Initial Clusters %d finalClusters %d\n"),initialCluster,finalCluster); 
	}

#endif

	FreeClusterList();

	statusMessage.printf(_T("Done, area coverage %3.2f"),(gSArea/gBArea)*100.f);
	Bail(ip,statusMessage,0);


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

}
예제 #17
0
void	UnwrapMod::RebuildEdges()
	{
	if (mode == ID_SKETCHMODE)
		SetMode(ID_MOVE);


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

	}

/*
BitArray holdVSel(vsel);


	BOOL holdSyncMode = fnGetSyncSelectionMode();
	fnSetSyncSelectionMode(FALSE);


	TVMaps.BuildEdges(  );
	//PELT
	TVMaps.BuildGeomEdges(  );

	if (esel.GetSize() != TVMaps.ePtrList.Count())
		{
		esel.SetSize(TVMaps.ePtrList.Count());
		esel.ClearAll();
		}

	if (gesel.GetSize() != TVMaps.gePtrList.Count())
		{
		gesel.SetSize(TVMaps.gePtrList.Count());
		gesel.ClearAll();
		}

	//FP 05/26/06 : PELT Mapping - CER Bucket #370291
	//When the topology of the object changes, the seams bits array need to be updated.  
	//By clearing it there, the update will be done each time the topology changes
	if (peltData.seamEdges.GetSize() != TVMaps.gePtrList.Count())
		{
		peltData.seamEdges.SetSize(TVMaps.gePtrList.Count());
		peltData.seamEdges.ClearAll();
		}




	vsel = holdVSel;

	fnSetSyncSelectionMode(holdSyncMode);

	usedVertices.SetSize(TVMaps.v.Count());
	usedVertices.ClearAll();

	for (int i = 0; i < TVMaps.f.Count(); i++)
		{
		int faceIndex = i;
		for (int k = 0; k < TVMaps.f[faceIndex]->count; k++)
			{
			if (!(TVMaps.f[faceIndex]->flags & FLAG_DEAD))
				{
				int vertIndex = TVMaps.f[faceIndex]->t[k];
				usedVertices.Set(vertIndex);
				if (objType == IS_PATCH)
					{
					if ((TVMaps.f[faceIndex]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[faceIndex]->vecs))
						{
						if (TVMaps.f[faceIndex]->flags & FLAG_INTERIOR)
							{
							vertIndex = TVMaps.f[faceIndex]->vecs->interiors[k];
							if ((vertIndex >=0) && (vertIndex < usedVertices.GetSize()))
								usedVertices.Set(vertIndex);
							}
						vertIndex = TVMaps.f[faceIndex]->vecs->handles[k*2];
						if ((vertIndex >=0) && (vertIndex < usedVertices.GetSize()))
							usedVertices.Set(vertIndex);
						vertIndex = TVMaps.f[faceIndex]->vecs->handles[k*2+1];
						if ((vertIndex >=0) && (vertIndex < usedVertices.GetSize()))
							usedVertices.Set(vertIndex);
						}
					}
				}
			}
		}

	//PELT
	for (int i = 0; i < peltData.springEdges.Count(); i++)
	{
		int vertIndex = peltData.springEdges[i].v1;
		if (vertIndex != -1)
			usedVertices.Set(vertIndex);
		vertIndex = peltData.springEdges[i].v2;
		if (vertIndex != -1)
			usedVertices.Set(vertIndex);

		vertIndex = peltData.springEdges[i].vec1;
		if ( (vertIndex != -1) && (vertIndex < usedVertices.GetSize()))
			usedVertices.Set(vertIndex);
		vertIndex = peltData.springEdges[i].vec2;
		if ( (vertIndex != -1) && (vertIndex < usedVertices.GetSize()))
			usedVertices.Set(vertIndex);

	}
	BuildEdgeDistortionData();
*/
}
예제 #18
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();

}