void UnwrapMod::BuildUsedList(BitArray &usedVerts, ClusterClass *cluster) { usedVerts.SetSize(TVMaps.v.Count()); usedVerts.ClearAll(); for (int j =0; j < cluster->faces.Count(); j++) { int faceIndex = cluster->faces[j]; for (int k = 0; k < TVMaps.f[faceIndex]->count; k++) { //need to put patch handles in here also int index = TVMaps.f[faceIndex]->t[k]; usedVerts.Set(index); if ((TVMaps.f[faceIndex]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[faceIndex]->vecs)) { index = TVMaps.f[faceIndex]->vecs->handles[k*2]; if ((index >= 0) && (index < usedVerts.GetSize())) usedVerts.Set(index); index = TVMaps.f[faceIndex]->vecs->handles[k*2+1]; if ((index >= 0) && (index < usedVerts.GetSize())) usedVerts.Set(index); if (TVMaps.f[faceIndex]->flags & FLAG_INTERIOR) { index = TVMaps.f[faceIndex]->vecs->interiors[k]; if ((index >= 0) && (index < usedVerts.GetSize())) usedVerts.Set(index); } } } } }
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]); } }
static void AssignSetMatchSize(BitArray &dst, BitArray &src) { int size = dst.GetSize(); dst = src; if (dst.GetSize() != size) { dst.SetSize(size, TRUE); } }
void EditFaceDataModData::SetFaceValue (BitArray & faces, float val) { for (int i=0; i<faces.GetSize(); i++) { if (!faces[i]) continue; mFacesAffected.Set (i); mtNewFaceValues[i] = val; } }
int ParticleChannelInt::Delete(BitArray& toRemove) { int checkCount = min(toRemove.GetSize(), Count()); if (isGlobal()) { // find number of set bit in the "count" range int numRemove = 0; for(int i=0; i<checkCount; i++) if (toRemove[i] != 0) numRemove++; _globalCount() -= numRemove; return globalCount(); } else { int i, j; for (i = j = 0; i < data().Count(); i++) { if (i < checkCount && toRemove[i] != 0) continue; if (i != j) _data(j) = data(i); j++; } if (j < data().Count()) _data().SetCount(j); return data().Count(); } }
void UVW_ChannelClass::MarkDeadVertices() { BitArray usedVerts; usedVerts.SetSize(v.Count()); usedVerts.ClearAll(); for (int i =0; i < f.Count(); i++) { if (!(f[i]->flags & FLAG_DEAD)) { for (int j=0; j < f[i]->count; j++) { int id = f[i]->t[j]; if (id < usedVerts.GetSize()) usedVerts.Set(id); if ((f[i]->flags & FLAG_CURVEDMAPPING) && (f[i]->vecs)) { id = f[i]->vecs->handles[j*2]; if (id < usedVerts.GetSize()) usedVerts.Set(id); id = f[i]->vecs->handles[j*2+1]; if (id < usedVerts.GetSize()) usedVerts.Set(id); if (f[i]->flags & FLAG_INTERIOR) { id = f[i]->vecs->interiors[j]; if (id < usedVerts.GetSize()) usedVerts.Set(id); } } } } } for (int i =0; i < v.Count(); i++) { if (i < usedVerts.GetSize()) { BOOL isRigPoint = v[i].GetFlag() & FLAG_RIGPOINT; if (!usedVerts[i] && (!isRigPoint)) { v[i].SetDead(); } } } }
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()); }
void EditFaceDataRestore::Restore(int isUndo) { if (firstFace < 0) return; if (isUndo && !after_called) After(); for (int i=firstFace; i<faces.GetSize(); i++) { if (!faces[i]) continue; if (!set_before[i]) modData->ResetFace (i); else modData->SetFaceValue (i, before[i]); } mod->ValueChanged (); }
IObject* ParticleChannelMap::Split(BitArray& toSplit) { // SysUtil::NeedToImplementLater(); // TODO: optimize the implementation ParticleChannelMap* newChannel = (ParticleChannelMap*)Clone(); Delete(toSplit); BitArray reverse = ~toSplit; if (reverse.GetSize() != newChannel->Count()) reverse.SetSize(newChannel->Count(), TRUE); newChannel->Delete(reverse); return newChannel; }
void EditFaceDataModData::DescribeSelection (int & numFaces, int & whichFace, float & value, bool &valueDetermined) { numFaces = 0; for (int i=0; i<mFaceSel.GetSize(); i++) { if (!mFaceSel[i]) continue; if (!numFaces) { whichFace = i; value = FaceValue (i); } else if (valueDetermined) { if (value != FaceValue(i)) valueDetermined = false; } numFaces++; } }
void EditPolyData::SelectByMaterial (EditPolyMod *pMod) { if (pMod->GetMNSelLevel() != MNM_SL_FACE) return; if (!mpMesh) return; int clear = pMod->getParamBlock()->GetInt (epm_material_selby_clear); int matInt = pMod->getParamBlock()->GetInt (epm_material_selby); MtlID matID = (MtlID) matInt; SetupNewSelection (MNM_SL_FACE); BitArray *pSel = GetNewSelection (); for (int i=0; i<pSel->GetSize(); i++) { if (mpMesh->f[i].material == matID) pSel->Set(i); } ApplyNewSelection (pMod, !clear); }
void EditPolyData::SelectBySmoothingGroup (EditPolyMod *pMod) { if (pMod->GetMNSelLevel() != MNM_SL_FACE) return; if (!mpMesh) return; int clear = pMod->getParamBlock()->GetInt (epm_smoother_selby_clear); int smgInt = pMod->getParamBlock()->GetInt (epm_smoother_selby); DWORD *smg = (DWORD *) ((void *)&smgInt); SetupNewSelection (MNM_SL_FACE); BitArray *pSel = GetNewSelection (); for (int i=0; i<pSel->GetSize(); i++) { if (mpMesh->f[i].smGroup & (*smg)) pSel->Set(i); } ApplyNewSelection (pMod, !clear); }
void EditPolyData::TranslateNewSelection (int selLevelFrom, int selLevelTo) { if (!mpNewSelection) return; if (!mpMesh) { DbgAssert (0); return; } BitArray intermediateSelection; BitArray toSelection; switch (selLevelFrom) { case EPM_SL_VERTEX: switch (selLevelTo) { case EPM_SL_EDGE: mSelConv.VertexToEdge (*mpMesh, *mpNewSelection, toSelection); break; case EPM_SL_BORDER: mSelConv.VertexToEdge (*mpMesh, *mpNewSelection, intermediateSelection); mSelConv.EdgeToBorder (*mpMesh, intermediateSelection, toSelection); break; case EPM_SL_FACE: mSelConv.VertexToFace (*mpMesh, *mpNewSelection, toSelection); break; case EPM_SL_ELEMENT: mSelConv.VertexToFace (*mpMesh, *mpNewSelection, intermediateSelection); mSelConv.FaceToElement (*mpMesh, intermediateSelection, toSelection); break; } break; case EPM_SL_EDGE: if (selLevelTo == EPM_SL_BORDER) { mSelConv.EdgeToBorder (*mpMesh, *mpNewSelection, toSelection); } break; case EPM_SL_FACE: if (selLevelTo == EPM_SL_ELEMENT) { mSelConv.FaceToElement (*mpMesh, *mpNewSelection, toSelection); } break; } if (toSelection.GetSize() == 0) return; *mpNewSelection = toSelection; }
float EditFaceDataModData::FaceValue (int faceID) { if (faceID<0) return 0.0f; if (faceID>mFacesAffected.GetSize()) return 0.0f; if (mFacesAffected[faceID]) return mtNewFaceValues[faceID]; IFaceDataMgr *pFDMgr = NULL; if (mpCacheMesh && (faceID < mpCacheMesh->numFaces)) { // Get the face data manager from the mesh: pFDMgr = static_cast<IFaceDataMgr*>(mpCacheMesh->GetInterface (FACEDATAMGR_INTERFACE)); } if (mpCacheMNMesh && (faceID < mpCacheMNMesh->numf)) { // Get the face data manager from the mesh: pFDMgr = static_cast<IFaceDataMgr*>(mpCacheMNMesh->GetInterface (FACEDATAMGR_INTERFACE)); } if (pFDMgr == NULL) return 0.0f; SampleFaceData* fdc = dynamic_cast<SampleFaceData*>(pFDMgr->GetFaceDataChan( FACE_MAXSAMPLEUSE_CLSID )); if (!fdc) return 0.0f; float val; if (!fdc->GetValue (faceID, val)) return 0.0f; return val; }
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; } } } }
void ResetFace (int faceID) { if ((faceID>=0)&&(faceID<mFacesAffected.GetSize())) mFacesAffected.Clear(faceID); }
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); } } } }
void EditFaceDataModData::SetFaceValue (int faceID, float val) { if (faceID<0) return; if (faceID>mFacesAffected.GetSize()) return; mFacesAffected.Set (faceID); mtNewFaceValues[faceID] = val; }
void EditFaceDataModData::ResetFace (BitArray & faces) { for (int i=0; i<faces.GetSize(); i++) { if (!faces[i]) continue; mFacesAffected.Clear (i); } }
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); } } } } } } }
int NumFaces () { return mFaceSel.GetSize(); }
IGeometryChecker::ReturnVal MissingUVCoordinatesChecker::GeometryCheck(TimeValue t,INode *nodeToCheck, IGeometryChecker::OutputVal &val) { val.mIndex.ZeroCount(); if(IsSupported(nodeToCheck)) { LARGE_INTEGER ups,startTime; QueryPerformanceFrequency(&ups); QueryPerformanceCounter(&startTime); //used to see if we need to pop up a dialog bool compute = true; bool checkTime = GetIGeometryCheckerManager()->GetAutoUpdate();//only check time for the dialog if auto update is active! UVWChannel uvmesh; ObjectState os = nodeToCheck->EvalWorldState(t); Object *obj = os.obj; if(os.obj->IsSubClassOf(triObjectClassID)) { TriObject *tri = dynamic_cast<TriObject *>(os.obj); if(tri) { BitArray arrayOfVertices; arrayOfVertices.SetSize(tri->mesh.numVerts); arrayOfVertices.ClearAll(); IGeometryChecker::ReturnVal returnval=IGeometryChecker::eFail; int numChannels = tri->mesh.getNumMaps(); int index; for(int i=0;i<numChannels;++i) { if(tri->mesh.mapSupport(i)) { MeshMap *map = &tri->mesh.Map(i); if(map->getNumVerts()>0 &&map->getNumFaces()>0) { returnval= TypeReturned(); int numFaces = map->getNumFaces(); TVFace * tvFaces = map->tf; UVVert * uvVerts= map->tv; #pragma omp parallel for for(int faceIndex =0;faceIndex<numFaces;++faceIndex) { if(compute) { TVFace& tvFace = tvFaces[faceIndex]; Point3 tv = uvVerts[tvFace.t[0]]; if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z)) { index = tri->mesh.faces[faceIndex].v[0]; if(index>=0&&index<tri->mesh.numVerts) { #pragma omp critical { arrayOfVertices.Set(index); } } } tv = uvVerts[tvFace.t[1]]; if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z)) { index = tri->mesh.faces[faceIndex].v[1]; if(index>=0&&index<tri->mesh.numVerts) { #pragma omp critical { arrayOfVertices.Set(index); } } } tv = uvVerts[tvFace.t[2]]; if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z)) { index = tri->mesh.faces[faceIndex].v[2]; if(index>=0&&index<tri->mesh.numVerts) { #pragma omp critical { arrayOfVertices.Set(index); } } } if(checkTime==true) { #pragma omp critical { DialogChecker::Check(checkTime,compute,numFaces,startTime,ups); } } } } } } } if(arrayOfVertices.IsEmpty()==false) //we have overlapping faces { int localsize= arrayOfVertices.GetSize(); for(int i=0;i<localsize;++i) { if(arrayOfVertices[i]) val.mIndex.Append(1,&i); } } return returnval; } else return IGeometryChecker::eFail; } else if(os.obj->IsSubClassOf(polyObjectClassID)) { PolyObject *poly = dynamic_cast<PolyObject *>(os.obj); if(poly) { BitArray arrayOfVertices; arrayOfVertices.SetSize(poly->GetMesh().numv); arrayOfVertices.ClearAll(); IGeometryChecker::ReturnVal returnval=IGeometryChecker::eFail; int numChannels= poly->GetMesh().MNum(); int index; for(int i=0;i<numChannels;++i) { if(poly->GetMesh().M(i)) { MNMesh *mesh = &(poly->GetMesh()); MNMap *mnmap = mesh->M(i); if(mnmap&&mnmap->numv>0&&mnmap->numf>0) { returnval= TypeReturned(); int numFaces = mnmap->numf; #pragma omp parallel for for(int faceIndex =0;faceIndex<numFaces;++faceIndex) { if(compute) { Point3 tv; int a,b,c; MNMapFace *face = mnmap->F(faceIndex); UVVert * uvVerts= mnmap->v; for(int j=0;j<(face->deg);++j) { if(j==(face->deg-2)) { a = j; b = j+1; c = 0; } else if(j==(face->deg-1)) { a = j; b = 0; c = 1; } else { a = j; b = j+1; c = j+2; } tv = uvVerts[face->tv[a]]; if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z)) { index = mesh->f->vtx[a]; if(index>=0&&index<mesh->numv) { #pragma omp critical { arrayOfVertices.Set(index); } } } tv = uvVerts[face->tv[b]]; if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z)) { index = mesh->f->vtx[b]; if(index>=0&&index<mesh->numv) { #pragma omp critical { arrayOfVertices.Set(index); } } } tv = uvVerts[face->tv[c]]; if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z)) { index = mesh->f->vtx[c]; if(index>=0&&index<mesh->numv) { #pragma omp critical { arrayOfVertices.Set(index); } } } if(checkTime==true) { #pragma omp critical { DialogChecker::Check(checkTime,compute,numFaces,startTime,ups); } } } } } } } } if(arrayOfVertices.IsEmpty()==false) //we have overlapping faces { int localsize= arrayOfVertices.GetSize(); for(int i=0;i<localsize;++i) { if(arrayOfVertices[i]) val.mIndex.Append(1,&i); } } return returnval; } else return IGeometryChecker::eFail; } } return IGeometryChecker::eFail; }
IGeometryChecker::ReturnVal MultipleEdgeChecker::GeometryCheck(TimeValue t,INode *nodeToCheck, IGeometryChecker::OutputVal &val) { val.mIndex.ZeroCount(); if(IsSupported(nodeToCheck)) { LARGE_INTEGER ups,startTime; QueryPerformanceFrequency(&ups); QueryPerformanceCounter(&startTime); //used to see if we need to pop up a dialog bool compute = true; bool checkTime = GetIGeometryCheckerManager()->GetAutoUpdate();//only check time for the dialog if auto update is active! ObjectState os = nodeToCheck->EvalWorldState(t); Object *obj = os.obj; BitArray arrayOfEdges; //we fill this up with the verts, if not empty then we have isolated vets EdgeFaceList edgeList; if(os.obj->IsSubClassOf(triObjectClassID)) { TriObject *tri = dynamic_cast<TriObject *>(os.obj); if(tri) { Mesh &mesh = tri->GetMesh(); edgeList.CreateEdgeFaceList(mesh); if(checkTime) { DialogChecker::Check(checkTime,compute,mesh.numFaces,startTime,ups); if(compute==false) return IGeometryChecker::eFail; } arrayOfEdges.SetSize(CheckerMeshEdge::GetTotalNumEdges(mesh.numFaces)); arrayOfEdges.ClearAll(); } else return IGeometryChecker::eFail; } else if(os.obj->IsSubClassOf(polyObjectClassID)) { PolyObject *poly = dynamic_cast<PolyObject *>(os.obj); if(poly) { MNMesh &mnMesh = poly->GetMesh(); edgeList.CreateEdgeFaceList(mnMesh); if(checkTime) { DialogChecker::Check(checkTime,compute,mnMesh.numf,startTime,ups); if(compute==false) return IGeometryChecker::eFail; } arrayOfEdges.SetSize(mnMesh.nume); arrayOfEdges.ClearAll(); } else return IGeometryChecker::eFail; } #pragma omp parallel for for(int i=0;i<edgeList.mNumVertexEdges;++i) { for(int j=0;j<edgeList.mVertexEdges[i]->mEdges.Count();++j) { EdgeFaceList::Edge *localEdge = edgeList.mVertexEdges[i]->mEdges[j]; if(localEdge) { if(localEdge->mFaces.Count()>2) { #pragma omp critical { arrayOfEdges.Set(localEdge->mEdgeNum); } } } } } if(arrayOfEdges.IsEmpty()==false) //we have an isolated vierts { int localsize= arrayOfEdges.GetSize(); for(int i=0;i<localsize;++i) { if(arrayOfEdges[i]) val.mIndex.Append(1,&i); } } return TypeReturned(); } return IGeometryChecker::eFail; }
IGeometryChecker::ReturnVal OverlappedUVWFacesChecker::GeometryCheck(TimeValue t,INode *nodeToCheck, IGeometryChecker::OutputVal &val) { val.mIndex.ZeroCount(); if(IsSupported(nodeToCheck)) { UVWChannel uvmesh; ObjectState os = nodeToCheck->EvalWorldState(t); Object *obj = os.obj; if(os.obj->IsSubClassOf(triObjectClassID)) { TriObject *tri = dynamic_cast<TriObject *>(os.obj); if(tri) { BitArray arrayOfFaces; arrayOfFaces.SetSize(tri->mesh.numFaces); arrayOfFaces.ClearAll(); IGeometryChecker::ReturnVal returnval=IGeometryChecker::eFail; int numChannels = tri->mesh.getNumMaps(); for(int i=0;i<numChannels;++i) { if(tri->mesh.mapSupport(i)) { uvmesh.DeleteData(); uvmesh.SetWithMesh(&tri->mesh,i); if(uvmesh.GetNumOfFaces()>1) { //okay now run it with that uvmesh returnval = GeometryCheckWithUVMesh(uvmesh,t, nodeToCheck,arrayOfFaces); if(returnval ==IGeometryChecker::eFail) return returnval; } } } if(arrayOfFaces.IsEmpty()==false) //we have overlapping faces { int localsize= arrayOfFaces.GetSize(); for(int i=0;i<localsize;++i) { if(arrayOfFaces[i]) val.mIndex.Append(1,&i); } } return returnval; } else return IGeometryChecker::eFail; } else if(os.obj->IsSubClassOf(polyObjectClassID)) { PolyObject *poly = dynamic_cast<PolyObject *>(os.obj); if(poly) { BitArray arrayOfFaces; arrayOfFaces.SetSize(poly->GetMesh().numf); arrayOfFaces.ClearAll(); IGeometryChecker::ReturnVal returnval=IGeometryChecker::eFail; int numChannels= poly->GetMesh().MNum();//do this! for(int i=0;i<numChannels;++i) { if(poly->GetMesh().M(i)) { uvmesh.DeleteData(); uvmesh.SetWithMesh(&poly->GetMesh(),i); if(uvmesh.GetNumOfFaces()>1) { //okay now run it with that uvmesh returnval = GeometryCheckWithUVMesh(uvmesh,t, nodeToCheck,arrayOfFaces); if(returnval ==IGeometryChecker::eFail) return returnval; } } } if(arrayOfFaces.IsEmpty()==false) //we have overlapping faces { int localsize= arrayOfFaces.GetSize(); for(int i=0;i<localsize;++i) { if(arrayOfFaces[i]) val.mIndex.Append(1,&i); } } return returnval; } else return IGeometryChecker::eFail; } } return IGeometryChecker::eFail; }
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); } }
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; } } }
void UnwrapMod::fnUnfoldSelectedPolygons(int unfoldMethod, BOOL normalize) { // flatten selected polygons BailStart(); BitArray *polySel = fnGetSelectedPolygons(); BitArray holdPolySel; if (polySel == NULL) return; if (TVMaps.f.Count() == 0) return; if (!theHold.Holding()) { theHold.SuperBegin(); theHold.Begin(); } holdPolySel.SetSize(polySel->GetSize()); holdPolySel = *polySel; HoldPointsAndFaces(); Point3 normal(0.0f,0.0f,1.0f); BitArray oldSel = *fnGetSelectedPolygons(); Tab<Point3> mapNormal; mapNormal.SetCount(0); BOOL bContinue = BuildCluster( mapNormal, 5.0f, TRUE, TRUE); TSTR statusMessage; BitArray sel; sel.SetSize(TVMaps.f.Count()); if (bContinue) { for (int i =0; i < clusterList.Count(); i++) { sel.ClearAll(); for (int j = 0; j < clusterList[i]->faces.Count();j++) sel.Set(clusterList[i]->faces[j]); fnSelectPolygonsUpdate(&sel, FALSE); PlanarMapNoScale(clusterList[i]->normal); int per = (i * 100)/clusterList.Count(); statusMessage.printf("%s %d%%.",GetString(IDS_PW_STATUS_MAPPING),per); if (Bail(ip,statusMessage)) { i = clusterList.Count(); bContinue = FALSE; } } if ( (bContinue) && (clusterList.Count() > 1) ) { if (!ip) return; ModContextList mcList; INodeTab nodes; ip->GetModContexts(mcList,nodes); int objects = mcList.Count(); MeshTopoData *md = (MeshTopoData*)mcList[0]->localData; if (md == NULL) { theHold.Cancel(); theHold.SuperCancel(); return; } Tab<Point3> objNormList; BuildNormals(md,objNormList); //remove internal edges BitArray *selectedPolygons = fnGetSelectedPolygons(); Tab<int> clusterGroups; clusterGroups.SetCount(TVMaps.f.Count()); for (i =0; i < clusterGroups.Count(); i++) { clusterGroups[i] = -1; } //loop through all tagged edges and remove any that onely have one edhes selected for (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; int currentCluster = 0; 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 (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; 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); AlignCluster(i,connectedClusterIndex,innerFaceIndex, outerFaceIndex,edgeIndex); 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 ((!processedClusters[connectedClusterIndex]) && (connectedClusterIndex != 0) && (connectedClusterIndex != -1)) { edgesToBeProcessed.Append(1,&clusterList[clusterIndex]->borderData[i]); } } } } } vsel.SetSize(TVMaps.v.Count()); vsel.ClearAll(); for (i = 0; i < clusterList.Count(); i++) { for (int j =0; j < clusterList[i]->faces.Count(); j++) { int faceIndex = clusterList[i]->faces[j]; for (int k =0; k < TVMaps.f[faceIndex]->count; k++) { int vertexIndex = TVMaps.f[faceIndex]->t[k]; vsel.Set(vertexIndex); } } } //now weld the verts if (normalize) { NormalizeCluster(); } float tempWeld = weldThreshold; weldThreshold = 0.001f; WeldSelected(FALSE); weldThreshold = tempWeld; } FreeClusterList(); if (bContinue) { theHold.Accept(_T(GetString(IDS_PW_PLANARMAP))); theHold.SuperAccept(_T(GetString(IDS_PW_PLANARMAP))); fnSelectPolygonsUpdate(&holdPolySel, FALSE); theHold.Suspend(); fnSyncTVSelection(); theHold.Resume(); } else { theHold.Cancel(); theHold.SuperCancel(); } RebuildEdges(); theHold.Suspend(); fnSyncGeomSelection(); theHold.Resume(); NotifyDependents(FOREVER,PART_SELECT,REFMSG_CHANGE); InvalidateView(); }
bool FaceAffected (int faceID) { return ((faceID>=0)&&(faceID<mFacesAffected.GetSize())&&mFacesAffected[faceID]) ? true : false; }
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 UnwrapMod::AlignCluster(int baseCluster, int moveCluster, int innerFaceIndex, int outerFaceIndex,int edgeIndex) { //get edges that are coincedent int vInner[2]; int vOuter[2]; int vInnerVec[2]; int vOuterVec[2]; int ct = 0; int vct = 0; for (int i = 0; i < TVMaps.f[innerFaceIndex]->count; i++) { int innerIndex = TVMaps.f[innerFaceIndex]->v[i]; for (int j = 0; j < TVMaps.f[outerFaceIndex]->count; j++) { int outerIndex = TVMaps.f[outerFaceIndex]->v[j]; if (innerIndex == outerIndex) { vInner[ct] = TVMaps.f[innerFaceIndex]->t[i]; vOuter[ct] = TVMaps.f[outerFaceIndex]->t[j]; ct++; } } } vInnerVec[0] = -1; vInnerVec[1] = -1; vOuterVec[0] = -1; vOuterVec[1] = -1; ct = 0; if ( (TVMaps.f[innerFaceIndex]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[innerFaceIndex]->vecs) && (TVMaps.f[outerFaceIndex]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[outerFaceIndex]->vecs) ) { for (i = 0; i < TVMaps.f[innerFaceIndex]->count*2; i++) { int innerIndex = TVMaps.f[innerFaceIndex]->vecs->vhandles[i]; for (int j = 0; j < TVMaps.f[outerFaceIndex]->count*2; j++) { int outerIndex = TVMaps.f[outerFaceIndex]->vecs->vhandles[j]; if (innerIndex == outerIndex) { int vec = TVMaps.f[innerFaceIndex]->vecs->handles[i]; vInnerVec[ct] = vec; vec = TVMaps.f[outerFaceIndex]->vecs->handles[j]; vOuterVec[ct] = vec; ct++; } } } } //get align vector Point3 pInner[2]; Point3 pOuter[2]; pInner[0] = TVMaps.v[vInner[0]].p; pInner[1] = TVMaps.v[vInner[1]].p; pOuter[0] = TVMaps.v[vOuter[0]].p; pOuter[1] = TVMaps.v[vOuter[1]].p; Point3 offset = pInner[0] - pOuter[0]; Point3 vecA, vecB; vecA = Normalize(pInner[1] - pInner[0]); vecB = Normalize(pOuter[1] - pOuter[0]); float dot = DotProd(vecA,vecB); float angle = 0.0f; if (dot == -1.0f) angle = PI; else if (dot == 1.0f) angle = 0.f; else angle = acos(dot); if ((_isnan(angle)) || (!_finite(angle))) angle = 0.0f; // DebugPrint("Stop\n"); // angle = acos(dot); //DebugPrint("angle %f dot %f \n",angle, dot); /* DebugPrint(" VecA %f %f %f \n",vecA.x,vecA.y,vecA.z); DebugPrint(" VecB %f %f %f \n",vecB.x,vecB.y,vecB.z); */ Matrix3 tempMat(1); tempMat.RotateZ(angle); Point3 vecC = VectorTransform(tempMat,vecB); float negAngle = -angle; Matrix3 tempMat2(1); tempMat2.RotateZ(negAngle); Point3 vecD = VectorTransform(tempMat2,vecB); float la,lb; la = Length(vecA-vecC); lb = Length(vecA-vecD); if (la > lb) angle = negAngle; clusterList[moveCluster]->newX = offset.x; clusterList[moveCluster]->newY = offset.y; //build vert list //move those verts BitArray processVertList; processVertList.SetSize(TVMaps.v.Count()); processVertList.ClearAll(); for (i =0; i < clusterList[moveCluster]->faces.Count(); i++) { int faceIndex = clusterList[moveCluster]->faces[i]; for (int j =0; j < TVMaps.f[faceIndex]->count; j++) { int vertexIndex = TVMaps.f[faceIndex]->t[j]; processVertList.Set(vertexIndex); if ( (objType == IS_PATCH) && (TVMaps.f[faceIndex]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[faceIndex]->vecs)) { int vertIndex; if (TVMaps.f[faceIndex]->flags & FLAG_INTERIOR) { vertIndex = TVMaps.f[faceIndex]->vecs->interiors[j]; if ((vertIndex >=0) && (vertIndex < processVertList.GetSize())) processVertList.Set(vertIndex); } vertIndex = TVMaps.f[faceIndex]->vecs->handles[j*2]; if ((vertIndex >=0) && (vertIndex < processVertList.GetSize())) processVertList.Set(vertIndex); vertIndex = TVMaps.f[faceIndex]->vecs->handles[j*2+1]; if ((vertIndex >=0) && (vertIndex < processVertList.GetSize())) processVertList.Set(vertIndex); } } } for (i = 0; i < processVertList.GetSize(); i++) { if (processVertList[i]) { //DebugPrint("%d ",i); Point3 p = TVMaps.v[i].p; //move to origin p -= pOuter[0]; //rotate Matrix3 mat(1); mat.RotateZ(angle); p = p * mat; //move to anchor point p += pInner[0]; TVMaps.v[i].p = p; if (TVMaps.cont[i]) TVMaps.cont[i]->SetValue(0,&TVMaps.v[i].p); } } if ((vInnerVec[0] != -1) && (vInnerVec[1] != -1) && (vOuterVec[0] != -1) && (vOuterVec[1] != -1)) { TVMaps.v[vOuterVec[0]].p = TVMaps.v[vInnerVec[0]].p; if (TVMaps.cont[vOuterVec[0]]) TVMaps.cont[vOuterVec[0]]->SetValue(0,&TVMaps.v[vInnerVec[0]].p); TVMaps.v[vOuterVec[1]].p = TVMaps.v[vInnerVec[1]].p; if (TVMaps.cont[vOuterVec[1]]) TVMaps.cont[vOuterVec[1]]->SetValue(0,&TVMaps.v[vInnerVec[1]].p); } }