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