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 } }
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); }