Example #1
0
void EditFaceDataModData::ApplyChanges (MNMesh & mesh) {
	// Make sure we're sized correctly for this mesh.
	// (NOTE: If the user reduces, then increases input number of faces, we lose data.)
	if (mesh.numf != mFaceSel.GetSize()) SynchSize (mesh.numf);

	// Set the selection:
	mesh.FaceSelect (mFaceSel);

	// Get the face data manager from the mesh:
	DebugPrint ("EditFaceDataMod: Getting manager from MNMesh (0x%08x)\n", &mesh);
	IFaceDataMgr *pFDMgr = static_cast<IFaceDataMgr*>(mesh.GetInterface (FACEDATAMGR_INTERFACE));
	if (pFDMgr == NULL) return;

	SampleFaceData* fdc = dynamic_cast<SampleFaceData*>(pFDMgr->GetFaceDataChan( FACE_MAXSAMPLEUSE_CLSID ));
	if ( fdc == NULL ) {
		// The mesh does not have our sample face-data channel so we will add it here
		fdc = new SampleFaceData();
		fdc->FacesCreated (0, mFaceSel.GetSize());
		pFDMgr->AddFaceDataChan( fdc );
	}

	if (!mFacesAffected.NumberSet ()) return;

	for (int i=0; i<mFacesAffected.GetSize(); i++) {
		if (!mFacesAffected[i]) continue;
		fdc->SetValue (i, mtNewFaceValues[i]);
	}
}
Example #2
0
void EditFaceDataMod::GetSubObjectTMs (SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc) {
	if (!mc->localData) return;
	if (selLevel == SEL_OBJECT) return;	// shouldn't happen.
	EditFaceDataModData *modData = (EditFaceDataModData *) mc->localData;

	Mesh *mesh = modData->GetCacheMesh();
	MNMesh *mnmesh = modData->GetCacheMNMesh();
	if (!mesh && !mnmesh) return;

	Matrix3 tm = node->GetObjectTM(t);
	Box3 box;
	if (mesh) {
		BitArray sel = mesh->VertexTempSel ();
		if (!sel.NumberSet()) return;
		for (int i=0; i<mesh->numVerts; i++) if (sel[i]) box += mesh->verts[i] * tm;
	} else {
		int numSel, which;
		float value;
		bool valueDetermined;
		modData->DescribeSelection (numSel, which, value, valueDetermined);
		if (!numSel) return;
		if (numSel==1) {
			for (int j=0; j<mnmesh->f[which].deg; j++) box += mnmesh->P(mnmesh->f[which].vtx[j]) * tm;
		} else {
			for (int i=0; i<mnmesh->numf; i++) {
				if (mnmesh->f[i].GetFlag (MN_DEAD)) continue;
				if (!modData->GetFaceSel()[i]) continue;
				for (int j=0; j<mnmesh->f[i].deg; j++) box += mnmesh->P(mnmesh->f[i].vtx[j]) * tm;
			}
		}
	}
	Matrix3 ctm(1);
	ctm.SetTrans (box.Center());
	cb->TM (ctm,0);
}
Example #3
0
void TriObject::GetDeformBBox(TimeValue t, Box3& box, Matrix3 *tm, BOOL useSel ) 
	{	
	if ( tm || useSel ) {
		box.Init();
		BitArray sel;
		BitArray vhide;
		float *vssel = NULL;
		if ( useSel ) {
			sel = mesh.VertexTempSel();
			vssel = mesh.getVSelectionWeights ();
		} else {
			vhide = mesh.vertHide;
			if (vhide.NumberSet ()) {
				for (int i=0; i<mesh.getNumFaces(); i++) {
					if (mesh.faces[i].Hidden ()) continue;
					for (int j=0; j<3; j++) vhide.Clear (mesh.faces[i].v[j]);
				}
			}
			}
		for ( int i = 0; i < mesh.getNumVerts(); i++ ) {
			if (!useSel && vhide[i]) continue;
			if ( !useSel || sel[i] || (vssel&&vssel[i])) {
				if ( tm ) {
					box += *tm * mesh.getVert(i);
				} else {
					box += mesh.getVert(i);
					}
				}
			}
	} else {
		box = mesh.getBoundingBox();
		}
	}
Example #4
0
void EditPolyData::CollapseDeadSelections (EditPolyMod *pMod, MNMesh & mesh)
{
	BitArray delSet;

	// Fix the vertex selection and hide arrays:
	int max = mesh.numv;
	if (max>mVertSel.GetSize()) max = mVertSel.GetSize ();
	delSet.SetSize (max);
	for (int i=0; i<max; i++) delSet.Set (i, mesh.v[i].GetFlag (MN_DEAD));
	if (delSet.NumberSet()>0)
	{
		if (theHold.Holding()) theHold.Put (new EditPolySelectRestore (pMod, this, EPM_SL_VERTEX));
		mVertSel.DeleteSet (delSet);
		if (theHold.Holding()) theHold.Put (new EditPolyHideRestore (pMod, this, false));
		mVertHide.DeleteSet (delSet);
	}

	// Fix the edge selection array:
	max = mesh.nume;
	if (max>mEdgeSel.GetSize()) max = mEdgeSel.GetSize ();
	delSet.SetSize (max);
	for (int i=0; i<max; i++) delSet.Set (i, mesh.e[i].GetFlag (MN_DEAD));
	if (delSet.NumberSet()>0)
	{
		if (theHold.Holding()) theHold.Put (new EditPolySelectRestore (pMod, this, EPM_SL_EDGE));
		mEdgeSel.DeleteSet (delSet);
	}

	// Fix the face selection and hide arrays:
	max = mesh.numf;
	if (max>mFaceSel.GetSize()) max = mFaceSel.GetSize ();
	delSet.SetSize (max);
	for (int i=0; i<max; i++) delSet.Set (i, mesh.f[i].GetFlag (MN_DEAD));
	if (delSet.NumberSet()>0)
	{
		if (theHold.Holding()) theHold.Put (new EditPolySelectRestore (pMod, this, EPM_SL_FACE));
		mFaceSel.DeleteSet (delSet);
		if (theHold.Holding()) theHold.Put (new EditPolyHideRestore (pMod, this, true));
		mFaceHide.DeleteSet (delSet);
	}
}
void MeshTopoData::RemoveDeadVerts(PatchMesh *mesh, int channel)
{
	Tab<Point3> vertList;
	Tab<int> idList;
	//copy over vertlist

	int ct = mesh->getNumMapVerts(channel);
	vertList.SetCount(ct);
	PatchTVert *tVerts = mesh->mapVerts(channel);
	for (int i = 0; i < ct; i++)
		vertList[i] = tVerts[i].p;

	BitArray usedList;
	usedList.SetSize(ct);
	TVPatch *tvFace = NULL;
	if (!mesh->getMapSupport(channel))
	{
		return;
	}

	tvFace = mesh->tvPatches[channel];
	if (tvFace == NULL) return;

	for (int i =0; i < mesh->numPatches; i++)
	{
		int pcount = 3;
		if (mesh->patches[i].type == PATCH_QUAD) pcount = 4;

		for (int j = 0; j < pcount; j++)
		{
			int index = tvFace[i].tv[j];
			usedList.Set(index);
			if (!(mesh->patches[i].flags & PATCH_LINEARMAPPING))
			{
				if (!(mesh->patches[i].flags & PATCH_AUTO))
				{
					index = tvFace[i].interiors[j];
					if ((index >= 0) && (index < usedList.GetSize())) usedList.Set(index);
				}
				index = tvFace[i].handles[j*2];
				if ((index >= 0) && (index < usedList.GetSize())) usedList.Set(index);
				index = tvFace[i].handles[j*2+1];
				if ((index >= 0) && (index < usedList.GetSize())) usedList.Set(index);

			}
		}
	}
	mesh->setNumMapVerts (channel,usedList.NumberSet(),TRUE);

	int current = 0;
	tVerts = mesh->mapVerts(channel);

	for (int i = 0; i < ct; i++)
	{
		if (usedList[i])
		{
			tVerts[current].p = vertList[i];
			//now fix up faces
			for (int j = 0; j < mesh->numPatches; j++)
			{
				int pcount = 3;
				if (mesh->patches[j].type == PATCH_QUAD) pcount = 4;

				for (int k = 0; k < pcount; k++)
				{
					int index = tvFace[j].tv[k];
					if (index == i)
					{
						tvFace[j].tv[k] = current;
					}

					index = tvFace[j].interiors[k];
					if ((index >=0) && (index == i))
					{
						tvFace[j].interiors[k] = current;
					}
					index = tvFace[j].handles[k*2];
					if ((index >=0) && (index == i))
					{
						tvFace[j].handles[k*2] = current;
					}
					index = tvFace[j].handles[k*2+1];
					if ((index >=0) && (index == i))
					{
						tvFace[j].handles[k*2+1] = current;
					}


				}

			}
			current++;
		}
}

}
void MeshTopoData::BuildInitialMapping(PatchMesh *msh)
{
	//build bounding box
	Box3 bbox;
	bbox.Init();
	//normalize the length width height
	for (int i = 0; i < TVMaps.f.Count(); i++)
	{
		int pcount = 3;
		pcount = TVMaps.f[i]->count;
		for (int j = 0; j < pcount; j++)
		{
			bbox += TVMaps.geomPoints[TVMaps.f[i]->v[j]];
			if (TVMaps.f[i]->flags & FLAG_CURVEDMAPPING)
			{
				if (TVMaps.f[i]->vecs)
				{
					bbox += TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2]];
					bbox += TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2+1]];
					if (TVMaps.f[i]->flags & FLAG_INTERIOR)
					{
						bbox += TVMaps.geomPoints[TVMaps.f[i]->vecs->vinteriors[j]];
					}
				}
			}

		}

	}
	Tab<int> indexList;

	int vct = msh->numVecs+msh->numVerts;
	indexList.SetCount(vct);
	BitArray usedIndex;
	usedIndex.SetSize(vct);
	usedIndex.ClearAll();

	for (int i = 0; i < vct; i++)
		indexList[i] = -1;

	for (int i = 0; i < TVMaps.f.Count(); i++)
	{
		if (!(TVMaps.f[i]->flags & FLAG_DEAD))
		{
			int pcount = 3;
			pcount = TVMaps.f[i]->count;

			for (int j = 0; j < pcount; j++)
			{
				//		usedIndex.Set(TVMaps.f[i].t[j]);
				usedIndex.Set(msh->patches[i].v[j]);
				if (TVMaps.f[i]->flags & FLAG_CURVEDMAPPING)
				{
					if (TVMaps.f[i]->vecs)
					{
						usedIndex.Set(msh->patches[i].vec[j*2]+msh->numVerts);
						usedIndex.Set(msh->patches[i].vec[j*2+1]+msh->numVerts);
						if (TVMaps.f[i]->flags & FLAG_INTERIOR)
						{
							usedIndex.Set(msh->patches[i].interior[j]+msh->numVerts);

						}
					}	
				}

			}
		}

	}

	int ct = 0;
	for (int i = 0; i < usedIndex.GetSize(); i++)
	{
		if (usedIndex[i])
			indexList[i] = ct++;

	}

	TVMaps.v.SetCount(usedIndex.NumberSet());
	mVSel.SetSize(usedIndex.NumberSet());

	//watje 10-19-99 bug 213437  to prevent a divide by 0 which gives you a huge u,v, or w value
	if (bbox.Width().x == 0.0f) bbox += Point3(0.5f,0.0f,0.0f);
	if (bbox.Width().y == 0.0f) bbox += Point3(0.0f,0.5f,0.0f);
	if (bbox.Width().z == 0.0f) bbox += Point3(0.0f,0.0f,0.5f);

	for (int i = 0; i < TVMaps.f.Count(); i++)
	{
		if (!(TVMaps.f[i]->flags & FLAG_DEAD))
		{
			int pcount = 3;
			pcount = TVMaps.f[i]->count;

			TVMaps.f[i]->flags &= ~FLAG_DEAD;
			for (int j = 0; j < pcount; j++)
			{
				int index;
				int a = msh->patches[i].v[j];
				index = indexList[a];
				TVMaps.f[i]->t[j] = index;
				Point3 uv(	TVMaps.geomPoints[TVMaps.f[i]->v[j]].x/bbox.Width().x + 0.5f,
							TVMaps.geomPoints[TVMaps.f[i]->v[j]].y/bbox.Width().y + 0.5f,
							TVMaps.geomPoints[TVMaps.f[i]->v[j]].z/bbox.Width().z + 0.5f);

				TVMaps.v[index].SetP(uv);
				TVMaps.v[index].SetInfluence(0.f);
				TVMaps.v[index].SetFlag(0);
				TVMaps.v[index].SetControlID(-1);
				if (TVMaps.f[i]->flags & FLAG_CURVEDMAPPING)
				{
					if (TVMaps.f[i]->vecs)
					{
						//					usedIndex.Set(msh->patches[i].vec[j*2]+msh->numVerts);
						//					usedIndex.Set(msh->patches[i].vec[j*2+1]+msh->numVerts);
						int index;
						int a = msh->patches[i].vec[j*2]+msh->numVerts;
						index = indexList[a];
						TVMaps.f[i]->vecs->handles[j*2] = index;
						Point3 uv(	TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2]].x/bbox.Width().x + 0.5f,
									TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2]].y/bbox.Width().y + 0.5f,
									TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2]].z/bbox.Width().z + 0.5f);
									
						TVMaps.v[index].SetP(uv);  
						TVMaps.v[index].SetInfluence(0.f);
						TVMaps.v[index].SetFlag(0);
						TVMaps.v[index].SetControlID(-1);

						a = msh->patches[i].vec[j*2+1]+msh->numVerts;
						index = indexList[a];
						TVMaps.f[i]->vecs->handles[j*2+1] = index;
						uv.x = TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2+1]].x/bbox.Width().x + 0.5f;
						uv.y = TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2+1]].y/bbox.Width().y + 0.5f;
						uv.z = TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2+1]].z/bbox.Width().z + 0.5f;
						TVMaps.v[index].SetP(uv);  
						TVMaps.v[index].SetInfluence(0.f);
						TVMaps.v[index].SetFlag(0);
						TVMaps.v[index].SetControlID(-1);


						if (TVMaps.f[i]->flags & FLAG_INTERIOR)
						{
							int index;
							int a = msh->patches[i].interior[j]+msh->numVerts;
							index = indexList[a];
							TVMaps.f[i]->vecs->interiors[j] = index;
							uv.x = TVMaps.geomPoints[TVMaps.f[i]->vecs->vinteriors[j]].x/bbox.Width().x + 0.5f;
							uv.y = TVMaps.geomPoints[TVMaps.f[i]->vecs->vinteriors[j]].y/bbox.Width().y + 0.5f;
							uv.z = TVMaps.geomPoints[TVMaps.f[i]->vecs->vinteriors[j]].z/bbox.Width().z + 0.5f;
							TVMaps.v[index].SetP(uv);  									
							TVMaps.v[index].SetInfluence(0.f);
							TVMaps.v[index].SetFlag(0);
							TVMaps.v[index].SetControlID(-1);

						}
					}	
				}
			}
		}

	}


}
void MeshTopoData::BuildInitialMapping(MNMesh *msh)
{
	//build bounding box
	Box3 bbox;
	bbox.Init();

	int vertCount = 0;
	//normalize the length width height
	for (int i = 0; i < TVMaps.f.Count(); i++)
	{
		int pcount = 3;
		pcount = TVMaps.f[i]->count;
		vertCount += pcount;
		for (int j = 0; j < pcount; j++)
		{
			bbox += TVMaps.geomPoints[TVMaps.f[i]->v[j]];
		}

	}

	vertCount = msh->numv;
	Tab<int> indexList;

	indexList.SetCount(vertCount);
	BitArray usedIndex;
	usedIndex.SetSize(vertCount);
	usedIndex.ClearAll();

	for (int i = 0; i < vertCount; i++)
		indexList[i] = -1;

	for (int i = 0; i < TVMaps.f.Count(); i++)
	{
		if (!(TVMaps.f[i]->flags & FLAG_DEAD))
		{
			int pcount = 3;
			pcount = TVMaps.f[i]->count;
			for (int j = 0; j < pcount; j++)
			{
				usedIndex.Set(msh->f[i].vtx[j]);
			}
		}

	}

	int ct = 0;
	for (int i = 0; i < usedIndex.GetSize(); i++)
	{
		if (usedIndex[i])
			indexList[i] = ct++;

	}

	TVMaps.v.SetCount(usedIndex.NumberSet());
	mVSel.SetSize(usedIndex.NumberSet());

	//watje 10-19-99 bug 213437  to prevent a divide by 0 which gives you a huge u,v, or w value
	if (bbox.Width().x == 0.0f) bbox += Point3(0.5f,0.0f,0.0f);
	if (bbox.Width().y == 0.0f) bbox += Point3(0.0f,0.5f,0.0f);
	if (bbox.Width().z == 0.0f) bbox += Point3(0.0f,0.0f,0.5f);

	for (int i = 0; i < TVMaps.f.Count(); i++)
	{
		if (!(TVMaps.f[i]->flags & FLAG_DEAD))
		{
			int pcount = 3;
			pcount = TVMaps.f[i]->count;
			TVMaps.f[i]->flags &= ~FLAG_DEAD;
			for (int j = 0; j < pcount; j++)
			{
				int index;
				int a = msh->f[i].vtx[j];
				index = indexList[a];
				TVMaps.f[i]->t[j] = index;
				Point3 uv(	TVMaps.geomPoints[TVMaps.f[i]->v[j]].x/bbox.Width().x + 0.5f,
					TVMaps.geomPoints[TVMaps.f[i]->v[j]].y/bbox.Width().y + 0.5f,
					TVMaps.geomPoints[TVMaps.f[i]->v[j]].z/bbox.Width().z + 0.5f );
				TVMaps.v[index].SetP(uv);
				TVMaps.v[index].SetInfluence(0.f);
				TVMaps.v[index].SetFlag(0);
				TVMaps.v[index].SetControlID(-1);

			}

		}
	}

}
Example #8
0
File: mesh.cpp Project: 2asoft/xray
void UnwrapMod::BuildInitialMapping(Mesh *msh)
	{
//build bounding box
	Box3 bbox;
	bbox.Init();
//normalize the length width height
	for (int i = 0; i < TVMaps.f.Count(); i++)
		{
		int pcount = 3;
//	if (TVMaps.f[i].flags & FLAG_QUAD)
		pcount = TVMaps.f[i]->count;
		for (int j = 0; j < pcount; j++)
			{
			bbox += TVMaps.geomPoints[TVMaps.f[i]->v[j]];
			}

		}
	Tab<int> indexList;

	indexList.SetCount(TVMaps.f.Count() *4);
	BitArray usedIndex;
	usedIndex.SetSize(TVMaps.f.Count() *4);
	usedIndex.ClearAll();

	for (i = 0; i < TVMaps.f.Count()*4; i++)
		indexList[i] = -1;

	for (i = 0; i < TVMaps.f.Count(); i++)
		{
		if (!(TVMaps.f[i]->flags & FLAG_DEAD))
			{
			int pcount = 3;
//		if (TVMaps.f[i].flags & FLAG_QUAD) pcount = 4;
			pcount = TVMaps.f[i]->count;
			for (int j = 0; j < pcount; j++)
				{
				usedIndex.Set(msh->faces[i].v[j]);
				}
			}

		}

	int ct = 0;
	for (i = 0; i < usedIndex.GetSize(); i++)
		{
		if (usedIndex[i])
			indexList[i] = ct++;

		}

	TVMaps.v.SetCount(usedIndex.NumberSet());
	TVMaps.cont.SetCount(usedIndex.NumberSet());
	vsel.SetSize(usedIndex.NumberSet());

//watje 10-19-99 bug 213437  to prevent a divide by 0 which gives you a huge u,v, or w value
	if (bbox.Width().x == 0.0f) bbox += Point3(0.5f,0.0f,0.0f);
	if (bbox.Width().y == 0.0f) bbox += Point3(0.0f,0.5f,0.0f);
	if (bbox.Width().z == 0.0f) bbox += Point3(0.0f,0.0f,0.5f);

	for (i = 0; i < TVMaps.f.Count(); i++)
		{
		if (!(TVMaps.f[i]->flags & FLAG_DEAD))
			{
			int pcount = 3;
//		if (TVMaps.f[i].flags & FLAG_QUAD)	pcount = 4;
			pcount = TVMaps.f[i]->count;
			TVMaps.f[i]->flags &= ~FLAG_DEAD;
			for (int j = 0; j < pcount; j++)
				{
				int index;
				int a = msh->faces[i].v[j];
				index = indexList[a];
				TVMaps.f[i]->t[j] = index;
				TVMaps.v[index].p.x =  TVMaps.geomPoints[TVMaps.f[i]->v[j]].x/bbox.Width().x + 0.5f;
				TVMaps.v[index].p.y =  TVMaps.geomPoints[TVMaps.f[i]->v[j]].y/bbox.Width().y + 0.5f;
				TVMaps.v[index].p.z =  TVMaps.geomPoints[TVMaps.f[i]->v[j]].z/bbox.Width().z + 0.5f;
				TVMaps.v[index].influence =  0.f;
				TVMaps.v[index].flags =  0.f;
				TVMaps.cont[index] = NULL;
		
				}

			}
		}

	}
Example #9
0
File: mesh.cpp Project: 2asoft/xray
void UnwrapMod::MeshUpdateGData(Mesh *mesh, BitArray faceSel)
	{	


	gverts.d.SetCount(faceSel.GetSize()*4);

	gverts.sel.SetSize(faceSel.GetSize()*4,1);
	gverts.sel.ClearAll();

	Face *tf = mesh->faces;
	Point3 *tp = mesh->verts;

//isolate a vertex list of just the selected faces
	for (int i = 0; i < faceSel.GetSize(); i++)
		{
		if (faceSel[i])
			{
			for (int j = 0; j < 3; j++)
				{
				int index = tf[i].v[j];
				gverts.addPoint(index, tp[index]);
				}

			}
		}
//build new tv faces
	int ct = gfaces.Count();
	for (i =0; i < ct; i++)
		{
		if (gfaces[i]->vecs) delete gfaces[i]->vecs;
		gfaces[i]->vecs = NULL;
		if (gfaces[i]->t) delete [] gfaces[i]->t;
		gfaces[i]->t = NULL;
		if (gfaces[i]->v) delete [] gfaces[i]->v;
		gfaces[i]->v = NULL;

		delete gfaces[i];
		gfaces[i] = NULL;
		}
	gfaces.SetCount(faceSel.NumberSet());
	for (i =0; i < faceSel.NumberSet(); i++) gfaces[i] = NULL;

	ct = 0;
	for (i = 0; i < faceSel.GetSize(); i++)
		{
		if (faceSel[i])
			{
			UVW_TVFaceClass *t = new UVW_TVFaceClass;
			t->FaceIndex = i;
			t->flags = 0;
			t->t = new int[3];
			t->v = new int[3];
			t->count = 3;
			for (int j = 0; j < 3; j++)
				{
//find indes in our vert array
				t->t[j] = (int)tf[i].v[j];


				}


			t->flags = TVMaps.f[i]->flags;
			if (gfaces[ct]) gfaces[ct]->DeleteVec();
			if ((gfaces[ct]) && (gfaces[ct]->t)) 
				{
				delete [] gfaces[ct]->t;
				gfaces[ct]->t = NULL;
				}
			if ((gfaces[ct]) && (gfaces[ct]->v)) 
				{
				delete [] gfaces[ct]->v;
				gfaces[ct]->v = NULL;
				}
			if (gfaces[ct]) delete gfaces[ct];
			gfaces[ct++] = t;


			}
		}
	
	}
Example #10
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++;
		}
	}

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

}
Example #12
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();

}
Example #13
0
void DeletePatchParts(PatchMesh *patch, RPatchMesh *rpatch, BitArray &delVerts, BitArray &delPatches) 
{
	int patches = patch->getNumPatches();
	int verts = patch->getNumVerts();
	int vecs = patch->getNumVecs();
	int dest;

	// We treat vectors specially in order to clean up after welds.  First, we tag 'em all,
	// then untag only those on unselected patches so that any dangling vectors will be deleted.
	BitArray delVectors(vecs);
	delVectors.SetAll();

	// Untag vectors that are on nondeleted patches
	int i;
	for (i = 0; i < patches; ++i)
	{
		if (!delPatches[i])
		{
			Patch& p = patch->patches[i];
			int j;
			for (j = 0; j <(p.type * 2); ++j)
			{
				delVectors.Clear(p.vec[j]);
			}
			for (j = 0; j < p.type; ++j)
				delVectors.Clear(p.interior[j]);
		}
	}

	// Make a table of vertices that are still in use -- Used to
	// delete those vertices which are floating, unused, in space.
	BitArray usedVerts(verts);
	usedVerts.ClearAll();
	for (i = 0; i < patches; ++i)
	{
		if (!delPatches[i])
		{
			Patch& p = patch->patches[i];
			for (int j = 0; j < p.type; ++j)
			{
				usedVerts.Set(p.v[j]);
			}
		}
	}
	for (i = 0; i < verts; ++i)
	{
		if (!usedVerts[i])
			delVerts.Set(i);
	}

	// If we have texture vertices, handle them, too
	for (int chan = 0; chan < patch->getNumMaps(); ++chan)
	{
		int tverts = patch->numTVerts[chan];
		if (tverts && patch->tvPatches[chan])
		{
			BitArray delTVerts(tverts);
			delTVerts.SetAll();
			for (i = 0; i < patches; ++i)
			{
				if (!delPatches[i])
				{
					Patch& p = patch->patches[i];
					TVPatch& tp = patch->tvPatches[chan][i];
					for (int j = 0; j < p.type; ++j)
						delTVerts.Clear(tp.tv[j]);
				}
			}
			// Got the list of tverts to delete -- now delete 'em
			// Build a table of redirected texture vertex indices
			int newTVerts = tverts - delTVerts.NumberSet();
			IntTab tVertIndex;
			tVertIndex.SetCount(tverts);
			UVVert *newTVertArray = new UVVert[newTVerts];
			dest = 0;
			for (i = 0; i < tverts; ++i)
			{
				if (!delTVerts[i])
				{
					newTVertArray[dest] = patch->tVerts[chan][i];
					tVertIndex[i] = dest++;
				}
			}
			delete[] patch->tVerts[chan];
#if MAX_RELEASE <= 3100
			patch->tVerts[chan] = newTVertArray;
#else
			*(patch->tVerts[chan]) = *newTVertArray;
#endif
			patch->numTVerts[chan] = newTVerts;
			// Now, copy the untagged texture patches to a new array
			// While you're at it, redirect the vertex indices
			int newTVPatches = patches - delPatches.NumberSet();
			TVPatch *newArray = new TVPatch[newTVPatches];
			dest = 0;
			for (i = 0; i < patches; ++i)
			{
				if (!delPatches[i])
				{
					Patch& p = patch->patches[i];
					TVPatch& tp = newArray[dest++];
					tp = patch->tvPatches[chan][i];
					for (int j = 0; j < p.type; ++j)
						tp.tv[j] = tVertIndex[tp.tv[j]];
				}
			}
			delete[] patch->tvPatches[chan];
			patch->tvPatches[chan] = newArray;;
		}
	}

	// Build a table of redirected vector indices
	IntTab vecIndex;
	vecIndex.SetCount(vecs);
	int newVectors = vecs - delVectors.NumberSet();
	PatchVec *newVecArray = new PatchVec[newVectors];
	dest = 0;
	for (i = 0; i < vecs; ++i)
	{
		if (!delVectors[i])
		{
			newVecArray[dest] = patch->vecs[i];
			vecIndex[i] = dest++;
		}
		else
			vecIndex[i] = -1;
	}
	delete[] patch->vecs;
	patch->vecs = newVecArray;
	patch->numVecs = newVectors;

	// Build a table of redirected vertex indices
	int newVerts = verts - delVerts.NumberSet();
	IntTab vertIndex;
	vertIndex.SetCount(verts);
	PatchVert *newVertArray = new PatchVert[newVerts];
	BitArray newVertSel(newVerts);
	newVertSel.ClearAll();
	dest = 0;
	for (i = 0; i < verts; ++i)
	{
		if (!delVerts[i])
		{
			newVertArray[dest] = patch->verts[i];
			newVertSel.Set(dest, patch->vertSel[i]);
			// redirect & adjust attached vector list
			PatchVert& v = newVertArray[dest];
			for (int j = 0; j < v.vectors.Count(); ++j)
			{
				v.vectors[j] = vecIndex[v.vectors[j]];
				if (v.vectors[j] < 0)
				{
					v.vectors.Delete(j, 1);
					j--;	// realign index
				}
			}
			vertIndex[i] = dest++;
		}
	}
	delete[] patch->verts;
	patch->verts = newVertArray;
	patch->numVerts = newVerts;
	patch->vertSel = newVertSel;

	// Now, copy the untagged patches to a new array
	// While you're at it, redirect the vertex and vector indices
	int newPatches = patches - delPatches.NumberSet();
	Patch *newArray = new Patch[newPatches];
	BitArray newPatchSel(newPatches);
	newPatchSel.ClearAll();
	dest = 0;
	for (i = 0; i < patches; ++i)
	{
		if (!delPatches[i])
		{
			newArray[dest] = patch->patches[i];
			Patch& p = newArray[dest];
			int j;
			for (j = 0; j < p.type; ++j)
				p.v[j] = vertIndex[p.v[j]];
			for (j = 0; j <(p.type * 2); ++j)
				p.vec[j] = vecIndex[p.vec[j]];
			for (j = 0; j < p.type; ++j)
				p.interior[j] = vecIndex[p.interior[j]];
			newPatchSel.Set(dest++, patch->patchSel[i]);
		}
	}

	// Rebuild info in rpatch
	rpatch->DeleteAndSweep (delVerts, delPatches, *patch);

	delete[] patch->patches;
	patch->patches = newArray;;
	patch->numPatches = newPatches;
	patch->patchSel.SetSize(newPatches, TRUE);
	patch->patchSel = newPatchSel;
	patch->buildLinkages();
}
BOOL MeshTopoData::NormalMap(Tab<Point3*> *normalList, Tab<ClusterClass*> &clusterList, UnwrapMod *mod )
{

	if (TVMaps.f.Count() == 0) return FALSE;


	BitArray polySel = mFSel;



	BitArray holdPolySel = mFSel;



	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];
		ClusterClass *cluster = new ClusterClass();
		cluster->normal = mapNormal[i];
		cluster->ld = this;
		clusterList.Append(1,&cluster);
	}


	//check for type

	BOOL bContinue = TRUE;
	TSTR statusMessage;


	Tab<Point3> objNormList;         
	mod->BuildNormals(this,objNormList);

	if (objNormList.Count() == 0)
	{
		return FALSE;
	}

	BitArray skipFace;
	skipFace.SetSize(mFSel.GetSize());
	skipFace.ClearAll();
	int numberSet = mFSel.NumberSet();
	for (int i = 0; i < mFSel.GetSize(); i++)
	{
		if (!mFSel[i])
			skipFace.Set(i);
	}





	for (int i =0; i < objNormList.Count(); i++)
	{
		int index = -1;
		float angle = 0.0f;
		if (skipFace[i] == FALSE)
		{
			for (int j =0; j < clusterList.Count(); j++)
			{
				if (clusterList[j]->ld == this)
				{
					Point3 debugNorm = objNormList[i];
					float dot = DotProd(debugNorm,clusterList[j]->normal);//mapNormal[j]);
					float newAngle = (acos(dot));

					if ((dot >= 1.0f) || (newAngle <= angle) || (index == -1))
					{
						index = j;
						angle = newAngle;
					}
				}
			}
			if (index != -1)
			{
				clusterList[index]->faces.Append(1,&i);
			}
		}
	}


	

	BitArray sel;
	sel.SetSize(TVMaps.f.Count());
	
	for (int i =0; i < clusterList.Count(); i++)
	{
		if (clusterList[i]->ld == this)
		{
			sel.ClearAll();
			for (int j = 0; j < clusterList[i]->faces.Count();j++)
				sel.Set(clusterList[i]->faces[j]);
			if (sel.NumberSet() > 0)
			{
	//			fnSelectPolygonsUpdate(&sel, FALSE);
				mFSel = sel;
				PlanarMapNoScale(clusterList[i]->normal,mod);

			}

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

	


	for (int i =0; i < clusterList.Count(); i++)
	{
		if (clusterList[i]->faces.Count() == 0)
		{
			delete clusterList[i];
			clusterList.Delete(i,1);
			i--;
		}

	}

	BitArray clusterVerts;
	clusterVerts.SetSize(TVMaps.v.Count());
	
	for (int i =0; i < clusterList.Count(); i++)
	{
		
		if (clusterList[i]->ld == this)
		{
			clusterVerts.ClearAll();
			for (int j = 0; j < clusterList[i]->faces.Count(); j++)
			{
				int findex = clusterList[i]->faces[j];
				AddVertsToCluster(findex,clusterVerts, clusterList[i]);
			}
		}
	}
	mFSel = holdPolySel ;

	return bContinue;
}
BOOL	MeshTopoData::BuildCluster( Tab<Point3> normalList, float threshold, BOOL connected, BOOL cleanUpStrayFaces, MeshTopoData::GroupBy groupBy, Tab<ClusterClass*> &clusterList, UnwrapMod *mod)
{
	BitArray processedFaces;

	Tab<BorderClass> clusterBorder;

	BitArray sel;

	sel.SetSize(TVMaps.f.Count());


	processedFaces.SetSize(TVMaps.f.Count());
	processedFaces.ClearAll();

	//check for type

	float radThreshold = threshold * PI/180.0f;
	TSTR statusMessage;






	Tab<Point3> objNormList;
	mod->BuildNormals(this,objNormList);


	for (int i = 0; i < mFSel.GetSize(); i++)
	{
		if (!mFSel[i])
			processedFaces.Set(i);
	}

	//build normals

	AdjEdgeList *edges = NULL;
	BOOL deleteEdges = FALSE;
	if ((mesh) && (connected))
	{
		edges = new AdjEdgeList(*mesh);
		deleteEdges = TRUE;
	}
	if (connected)
	{
		BOOL done = FALSE;
		int currentNormal = 0;

		if (normalList.Count() == 0)
			done = TRUE;

		while (!done)
		{
			sel.ClearAll();
			//find the closest normal within the threshold
			float angDist = -1.0f;
			int hitIndex = -1;
			for (int i =0; i < objNormList.Count(); i++)
			{
				if (!processedFaces[i])
				{
					float cangle = acos(DotProd(normalList[currentNormal],objNormList[i]));
					if (((cangle < angDist) || (hitIndex == -1)) && (cangle < radThreshold))
					{
						angDist = cangle;
						hitIndex = i;
					}
				}
			}
			int bail = 0;
			if ( (hitIndex != -1) )
			{
//FIX HERE BY MAT OR SMGRP
				mod->SelectFacesByGroup( this,sel,hitIndex, normalList[currentNormal], threshold, FALSE, groupBy, objNormList,
					clusterBorder,
					edges);
				//add cluster
				if (sel.NumberSet() > 0)
				{
					//create a cluster and add it
					BitArray clusterVerts;
					clusterVerts.SetSize(TVMaps.v.Count());
					clusterVerts.ClearAll();

					ClusterClass *cluster = new ClusterClass();
					cluster->ld = this;
					BOOL hit = FALSE;
					cluster->normal = normalList[currentNormal];
					for (int j = 0; j < sel.GetSize(); j++)
					{
						if (sel[j] && (!processedFaces[j]))
						{
							//add to cluster
							processedFaces.Set(j,TRUE);
							cluster->faces.Append(1,&j);
							AddVertsToCluster(j,clusterVerts, cluster);
							hit = TRUE;
						}
					}

					cluster->borderData = clusterBorder;
					//add edges that were processed
					if (hit)
					{
						clusterList.Append(1,&cluster);
						bail++;
					}
					else
					{
						delete cluster;
					}

				}
			}  
			currentNormal++;
			if (currentNormal >= normalList.Count()) 
			{
				currentNormal = 0;
				if (bail == 0) done = TRUE;
			}


			int per = (processedFaces.NumberSet() * 100)/processedFaces.GetSize();
			statusMessage.printf(_T("%s %d%%."),GetString(IDS_PW_STATUS_BUILDCLUSTER),per);
			if (mod->Bail(mod->ip,statusMessage))
			{
				if (deleteEdges) delete edges;
				return FALSE;
			}


		}
	}
	else
	{  
		for (int i =0; i < normalList.Count(); i++)
		{
			sel.ClearAll();

			//find closest face norm
			mod->SelectFacesByNormals(this,sel,normalList[i], threshold, objNormList);
			//add cluster
			int numberSet = sel.NumberSet();
			int totalNumberSet = processedFaces.NumberSet();
			if ( numberSet > 0)
			{
				//create a cluster and add it
				ClusterClass *cluster = new ClusterClass();
				cluster->ld = this;
				BOOL hit = FALSE;
				cluster->normal = normalList[i];
				BitArray clusterVerts;
				clusterVerts.SetSize(TVMaps.v.Count());
				clusterVerts.ClearAll();
				for (int j = 0; j < sel.GetSize(); j++)
				{
					if (sel[j] && (!processedFaces[j]))
					{
						//add to cluster
						processedFaces.Set(j,TRUE);
						cluster->faces.Append(1,&j);
						AddVertsToCluster(j,clusterVerts, cluster);
						hit = TRUE;
					}
				}
				if (hit)
					clusterList.Append(1,&cluster);
				else delete cluster;
			}

			int per = (i * 100)/normalList.Count();
			statusMessage.printf(_T("%s %d%%."),GetString(IDS_PW_STATUS_BUILDCLUSTER),per);
			if (mod->Bail(mod->ip,statusMessage))
			{
				if (deleteEdges) delete edges;
				return FALSE;
			}

		}
	}
	//process the ramaining

	if (cleanUpStrayFaces)
	{
		//       Tab<int> tempSeedFaces = seedFaces;
		int ct = 0;
		if (mod->seedFaces.Count() > 0) ct = mod->seedFaces[0];
		while ( (processedFaces.NumberSet() != processedFaces.GetSize()) )
		{
			if (!processedFaces[ct])
			{
				if (connected)
				{
					mod->SelectFacesByGroup( this,sel,ct, objNormList[ct], threshold, FALSE,groupBy, objNormList,
						clusterBorder,
						edges);

				}
				else mod->SelectFacesByNormals(this,sel,objNormList[ct], threshold, objNormList);
				//add cluster
				if (sel.NumberSet() > 0)
				{
					//create a cluster and add it
					ClusterClass *cluster = new ClusterClass();
					cluster->ld = this;
					cluster->normal = objNormList[ct];
					BOOL hit = FALSE;

					BitArray clusterVerts;
					clusterVerts.SetSize(TVMaps.v.Count());
					clusterVerts.ClearAll();

					for (int j = 0; j < sel.GetSize(); j++)
					{
						if (sel[j] && (!processedFaces[j]))
						{
							//add to cluster
							processedFaces.Set(j,TRUE);
							cluster->faces.Append(1,&j);
							AddVertsToCluster(j,clusterVerts, cluster);
							hit = TRUE;
						}
					}
					if (connected)
					{
						cluster->borderData = clusterBorder;
					}
					if (hit)
					{
						clusterList.Append(1,&cluster);
					}
					else
					{
						delete cluster;
					}

				}

			}
			ct++;
			if (ct >= processedFaces.GetSize())
				ct =0;

			int per = (processedFaces.NumberSet() * 100)/processedFaces.GetSize();
			statusMessage.printf(_T("%s %d%%."),GetString(IDS_PW_STATUS_BUILDCLUSTER),per);
			if (mod->Bail(mod->ip,statusMessage))
			{
				if (deleteEdges) delete edges;
				return FALSE;
			}

		}
	}
	if (deleteEdges) delete edges;

	

	return TRUE;

}