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 UnwrapMod::fnAlignAndFit(int axis) { //get our selection Box3 bounds; bounds.Init(); //get the bounding box Point3 pnorm(0.0f,0.0f,0.0f); int ct = 0; TimeValue t = GetCOREInterface()->GetTime(); for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++) { MeshTopoData *ld = mMeshTopoData[ldID]; Matrix3 tm = mMeshTopoData.GetNodeTM(t,ldID); for (int k = 0; k < ld->GetNumberFaces(); k++) { if (ld->GetFaceSelected(k)) { // Grap the three points, xformed int pcount = 3; // if (gfaces[k].flags & FLAG_QUAD) pcount = 4; pcount = ld->GetFaceDegree(k);//gfaces[k]->count; Point3 temp_point[4]; for (int j=0; j<pcount; j++) { int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j]; bounds += ld->GetGeomVert(index) *tm;//gverts.d[index].p; if (j < 4) temp_point[j] = ld->GetGeomVert(index);//gverts.d[index].p; } pnorm += VectorTransform(Normalize(temp_point[1]-temp_point[0]^temp_point[2]-temp_point[1]),tm); ct++; } } } if (ct == 0) return; theHold.Begin(); SuspendAnimate(); AnimateOff(); pnorm = pnorm / (float) ct; Matrix3 tm(1); //if just a primary axis set the tm; Point3 center = bounds.Center(); // build the scale Point3 scale(bounds.Width().x ,bounds.Width().y , bounds.Width().z); if (scale.x == 0.0f) scale.x = 1.0f; if (scale.y == 0.0f) scale.y = 1.0f; if (scale.z == 0.0f) scale.z = 1.0f; if (axis == 0) // x axi { tm.SetRow(0,Point3(0.0f,-scale.y,0.0f)); tm.SetRow(1,Point3(0.0f,0.0f,scale.z)); tm.SetRow(2,Point3(scale.x,0.0f,0.0f)); if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP) || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP)) tm.SetRow(3,center); else if (fnGetMapMode() == CYLINDRICALMAP) { center.x = bounds.pmin.x; tm.SetRow(3,center); } Matrix3 ptm(1), id(1); tm = tm ; SetXFormPacket tmpck(tm,ptm); tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE); } else if (axis == 1) // y axi { tm.SetRow(0,Point3(scale.x,0.0f,0.0f)); tm.SetRow(1,Point3(0.0f,0.0f,scale.z)); tm.SetRow(2,Point3(0.0f,scale.y,0.0f)); if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP)|| (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP)) tm.SetRow(3,center); else if (fnGetMapMode() == CYLINDRICALMAP) { center.y = bounds.pmin.y; tm.SetRow(3,center); } Matrix3 ptm(1), id(1); tm = tm; SetXFormPacket tmpck(tm,ptm); tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE); } else if (axis == 2) //z axi { tm.SetRow(0,Point3(scale.x,0.0f,0.0f)); tm.SetRow(1,Point3(0.0f,scale.y,0.0f)); tm.SetRow(2,Point3(0.0f,0.0f,scale.z)); if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP)|| (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP)) tm.SetRow(3,center); else if (fnGetMapMode() == CYLINDRICALMAP) { center.z = bounds.pmin.z; tm.SetRow(3,center); } Matrix3 ptm(1), id(1); tm = tm; SetXFormPacket tmpck(tm,ptm); tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE); } else if (axis == 3) // normal { int numberOfSelectionGroups = 0; for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++) { MeshTopoData *ld = mMeshTopoData[ldID]; if (ld->GetFaceSelection().NumberSet()) numberOfSelectionGroups++; } if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP) || (numberOfSelectionGroups > 1)) { //get our tm Matrix3 tm; UnwrapMatrixFromNormal(pnorm,tm); Matrix3 itm = Inverse(tm); //find our x and y scale float xmax = 0.0f; float ymax = 0.0f; float zmax = 0.0f; Box3 localBounds; localBounds.Init(); for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++) { MeshTopoData *ld = mMeshTopoData[ldID]; Matrix3 tm = mMeshTopoData.GetNodeTM(t,ldID); for (int k = 0; k < ld->GetNumberFaces(); k++) { if (ld->GetFaceSelected(k)) { // Grap the three points, xformed int pcount = 3; // if (gfaces[k].flags & FLAG_QUAD) pcount = 4; pcount = ld->GetFaceDegree(k);//gfaces[k]->count; Point3 temp_point[4]; for (int j=0; j<pcount; j++) { int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j]; Point3 p = ld->GetGeomVert(index) * tm * itm;//gverts.d[index].p * itm; localBounds += p; } } } } // center = localBounds.Center(); xmax = localBounds.pmax.x - localBounds.pmin.x; ymax = localBounds.pmax.y - localBounds.pmin.y; zmax = localBounds.pmax.z - localBounds.pmin.z; if (xmax < 0.001f) xmax = 1.0f; if (ymax < 0.001f) ymax = 1.0f; if (zmax < 0.001f) zmax = 1.0f; Point3 vec; vec = Normalize(tm.GetRow(0)) * xmax; tm.SetRow(0,vec); vec = Normalize(tm.GetRow(1)) * ymax; tm.SetRow(1,vec); vec = Normalize(tm.GetRow(2)) * zmax; tm.SetRow(2,vec); tm.SetRow(3,center); Matrix3 ptm(1), id(1); tm = tm ; SetXFormPacket tmpck(tm,ptm); tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE); } else if ((fnGetMapMode() == CYLINDRICALMAP) || (fnGetMapMode() == SPHERICALMAP)|| (fnGetMapMode() == BOXMAP)) { for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++) { //get our first 2 rings Tab<int> openEdges; Tab<int> startRing; Tab<int> endRing; MeshTopoData *ld = mMeshTopoData[ldID]; //skip any local data that has no selections if (ld->GetFaceSelection().NumberSet() == 0) continue; Matrix3 nodeTM = mMeshTopoData.GetNodeTM(t,ldID); for (int i = 0; i < ld->GetNumberGeomEdges(); i++)//TVMaps.gePtrList.Count(); i++) { int numberSelectedFaces = 0; int ct = ld->GetGeomEdgeNumberOfConnectedFaces(i);//TVMaps.gePtrList[i]->faceList.Count(); for (int j = 0; j < ct; j++) { int faceIndex = ld->GetGeomEdgeConnectedFace(i,j);//TVMaps.gePtrList[i]->faceList[j]; if (ld->GetFaceSelected(faceIndex))//fsel[faceIndex]) numberSelectedFaces++; } if (numberSelectedFaces == 1) { openEdges.Append(1,&i,1000); } } GetOpenEdges(ld,openEdges, startRing); GetOpenEdges(ld,openEdges, endRing); Point3 zVec = pnorm; Point3 centerS(0.0f,0.0f,0.0f), centerE; if ((startRing.Count() != 0) && (endRing.Count() != 0)) { //get the center start Box3 BoundsS, BoundsE; BoundsS.Init(); BoundsE.Init(); //get the center end for (int i = 0; i < startRing.Count(); i++) { int eIndex = startRing[i]; int a = ld->GetGeomEdgeVert(eIndex,0);//TVMaps.gePtrList[eIndex]->a; int b = ld->GetGeomEdgeVert(eIndex,1);//TVMaps.gePtrList[eIndex]->b; BoundsS += ld->GetGeomVert(a) * nodeTM;//TVMaps.geomPoints[a]; BoundsS += ld->GetGeomVert(b) * nodeTM;//TVMaps.geomPoints[b]; } for (int i = 0; i < endRing.Count(); i++) { int eIndex = endRing[i]; int a = ld->GetGeomEdgeVert(eIndex,0);//TVMaps.gePtrList[eIndex]->a; int b = ld->GetGeomEdgeVert(eIndex,1);//TVMaps.gePtrList[eIndex]->b; BoundsE += ld->GetGeomVert(a) * nodeTM;//TVMaps.geomPoints[a]; BoundsE += ld->GetGeomVert(b) * nodeTM;//TVMaps.geomPoints[b]; } centerS = BoundsS.Center(); centerE = BoundsE.Center(); //create the vec zVec = centerE - centerS; } else if ((startRing.Count() != 0) && (endRing.Count() == 0)) { //get the center start Box3 BoundsS; BoundsS.Init(); //get the center end for (int i = 0; i < startRing.Count(); i++) { int eIndex = startRing[i]; int a = ld->GetGeomEdgeVert(eIndex,0);//TVMaps.gePtrList[eIndex]->a; int b = ld->GetGeomEdgeVert(eIndex,1);//TVMaps.gePtrList[eIndex]->b; BoundsS += ld->GetGeomVert(a) * nodeTM;//TVMaps.geomPoints[a]; BoundsS += ld->GetGeomVert(b) * nodeTM;//TVMaps.geomPoints[b]; } centerS = BoundsS.Center(); int farthestPoint= -1; Point3 fp; float farthestDist= 0.0f; for (int k=0; k < ld->GetNumberFaces(); k++) { if (ld->GetFaceSelected(k)) { // Grap the three points, xformed int pcount = 3; // if (gfaces[k].flags & FLAG_QUAD) pcount = 4; pcount = ld->GetFaceDegree(k);//gfaces[k]->count; for (int j=0; j<pcount; j++) { int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j]; Point3 p = ld->GetGeomVert(index)* nodeTM;//gverts.d[index].p; float d = LengthSquared(p-centerS); if ((d > farthestDist) || (farthestPoint == -1)) { farthestDist = d; farthestPoint = index; fp = p; } } } } centerE = fp; //create the vec zVec = centerE - centerS; } else { zVec = Point3(0.0f,0.0f,1.0f); } //get our tm Matrix3 tm; UnwrapMatrixFromNormal(zVec,tm); tm.SetRow(3,centerS); Matrix3 itm = Inverse(tm); //find our x and y scale float xmax = 0.0f; float ymax = 0.0f; float zmax = 0.0f; Box3 localBounds; localBounds.Init(); for (int k = 0; k < ld->GetNumberFaces(); k++)//gfaces.Count(); k++) { if (ld->GetFaceSelected(k)) { // Grap the three points, xformed int pcount = 3; // if (gfaces[k].flags & FLAG_QUAD) pcount = 4; pcount = ld->GetFaceDegree(k);//gfaces[k]->count; Point3 temp_point[4]; for (int j=0; j<pcount; j++) { int index = ld->GetFaceGeomVert(k,j);//gfaces[k]->t[j]; Point3 p = ld->GetGeomVert(index) * nodeTM * itm;//gverts.d[index].p * itm; localBounds += p; } } } center = localBounds.Center() * tm; if (fnGetMapMode() == CYLINDRICALMAP) { if ((startRing.Count() == 0) && (endRing.Count() == 0)) { centerS = center; centerS.z = localBounds.pmin.z; } else { centerS = centerS * itm; centerS.z = localBounds.pmin.z; centerS = centerS * tm; } } else if ((fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP)) { centerS = center; } Point3 bc = localBounds.Center(); bc.z = localBounds.pmin.z; bc = bc * tm; xmax = localBounds.pmax.x - localBounds.pmin.x; ymax = localBounds.pmax.y - localBounds.pmin.y; zmax = localBounds.pmax.z - localBounds.pmin.z; Point3 vec; vec = Normalize(tm.GetRow(0)) * xmax; tm.SetRow(0,vec); vec = Normalize(tm.GetRow(1)) * ymax; tm.SetRow(1,vec); vec = Normalize(tm.GetRow(2)) * zmax; tm.SetRow(2,vec); tm.SetRow(3,centerS); Matrix3 ptm(1), id(1); tm = tm; SetXFormPacket tmpck(tm,ptm); tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE); } } } ResumeAnimate(); if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == CYLINDRICALMAP) || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP)) ApplyGizmo(); theHold.Accept(GetString(IDS_MAPPING_ALIGN)); fnGetGizmoTM(); if (ip) ip->RedrawViews(ip->GetTime()); }
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++; } } }
void UnwrapMod::fnPaste(BOOL rotate) { //check for type TimeValue t = GetCOREInterface()->GetTime(); theHold.Begin(); HoldPointsAndFaces(); for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++) { MeshTopoData *ld = mMeshTopoData[ldID]; //check faces if just one selected normal paste with rotates //or if all faces where selected //or if first paste //hold the points and faces BitArray holdFaceSel(ld->GetFaceSelection()); BitArray subFaceSel; if ( ip && (ip->GetSubObjectLevel() == 0) ) { //convert our current selection into faces if (fnGetTVSubMode() == TVVERTMODE) ld->GetFaceSelFromVert(subFaceSel,FALSE); else if (fnGetTVSubMode() == TVEDGEMODE) { BitArray tempVSel; ld->GetVertSelFromEdge(tempVSel); BitArray vsel = ld->GetTVVertSelection(); BitArray holdVSel(vsel); ld->SetTVVertSelection(tempVSel);//vsel = tempVSel; ld->GetFaceSelFromVert(subFaceSel,FALSE); ld->SetTVVertSelection(holdVSel);//vsel = holdVSel; } else if (fnGetTVSubMode() == TVFACEMODE) { subFaceSel = ld->GetFaceSelection();//.SetSize(fsel.GetSize()); //subFaceSel = fsel; } } else { if (fnGetTVSubMode() == TVFACEMODE) { subFaceSel = ld->GetFaceSelection();//.SetSize(fsel.GetSize()); //subFaceSel = fsel; } } if ( (copyPasteBuffer.copyType == 0) || (copyPasteBuffer.copyType == 1) || (copyPasteBuffer.iRotate==0)) { int copyIndex = 0; Tab<int> vertexLookUpList; vertexLookUpList.SetCount(copyPasteBuffer.tVertData.Count()); BitArray faceSel = ld->GetFaceSelection(); for (int i =0; i < vertexLookUpList.Count(); i++) vertexLookUpList[i] = -1; if (copyPasteBuffer.copyType == 1) copyPasteBuffer.iRotate = 0; else { if (copyPasteBuffer.lastSel.GetSize() == faceSel.GetSize()) { if (copyPasteBuffer.lastSel == faceSel) { if (rotate) { copyPasteBuffer.iRotate++; } else copyPasteBuffer.iRotate = 0; } } } if (copyPasteBuffer.copyType == 2) copyPasteBuffer.iRotate = 0; copyPasteBuffer.lastSel = faceSel; //loop through selected faces for (int i =0; i < faceSel.GetSize(); i++) { if (faceSel[i]) { //make sure selected faces count = buffer face if (( i < ld->GetNumberFaces()/*TVMaps.f.Count()*/) && (copyIndex < copyPasteBuffer.faceData.Count())) { int degree = ld->GetFaceDegree(i); if (/*TVMaps.f[i]->count*/ degree == copyPasteBuffer.faceData[copyIndex]->count) { //if so set the face data indices as the same for (int j = 0; j < degree/*TVMaps.f[i]->count*/; j++) { //index into the texture vertlist int vid = (j + copyPasteBuffer.iRotate)%degree;//TVMaps.f[i]->count; int vertexIndex = copyPasteBuffer.faceData[copyIndex]->t[vid]; if (vertexLookUpList[vertexIndex] == -1) { Point3 p = copyPasteBuffer.tVertData[vertexIndex]; ld->AddTVVert(t, p, i, j, this,FALSE);//ld->AddPoint(p, i, j,FALSE); vertexLookUpList[vertexIndex] = ld->GetFaceTVVert(i,j);//TVMaps.f[i]->t[j]; } else ld->SetFaceTVVert(i,j,vertexLookUpList[vertexIndex]);//TVMaps.f[i]->t[j] = vertexLookUpList[vertexIndex]; if ((ld->GetFaceHasVectors(i)/*TVMaps.f[i]->vecs*/) && (copyPasteBuffer.faceData[copyIndex]->vecs) && (j < 4)) { int hid = (j*2 + (copyPasteBuffer.iRotate*2))%(/*TVMaps.f[i]->count*/degree*2); int handleIndex = copyPasteBuffer.faceData[copyIndex]->vecs->handles[hid]; if ((handleIndex >= 0) && (vertexLookUpList[handleIndex] == -1)) { Point3 p = copyPasteBuffer.tVertData[handleIndex]; ld->AddTVHandle(t,p, i, j*2,this,FALSE); vertexLookUpList[handleIndex] = ld->GetFaceTVHandle(i,j*2);// TVMaps.f[i]->vecs->handles[j*2]; } else ld->SetFaceTVHandle(i,j*2,vertexLookUpList[handleIndex]);//TVMaps.f[i]->vecs->handles[j*2] = vertexLookUpList[handleIndex]; hid = (j*2 + (copyPasteBuffer.iRotate*2))%(degree/*TVMaps.f[i]->count*/*2)+1; handleIndex = copyPasteBuffer.faceData[copyIndex]->vecs->handles[hid]; if ((handleIndex >= 0) && (vertexLookUpList[handleIndex] == -1)) { Point3 p = copyPasteBuffer.tVertData[handleIndex]; ld->AddTVHandle(t,p, i, j*2+1,this,FALSE); vertexLookUpList[handleIndex] = ld->GetFaceTVHandle(i,j*2+1);//TVMaps.f[i]->vecs->handles[j*2+1]; } else ld->SetFaceTVHandle(i,j*2+1,vertexLookUpList[handleIndex]);//TVMaps.f[i]->vecs->handles[j*2+1] = vertexLookUpList[handleIndex]; int iid = (j + (copyPasteBuffer.iRotate))%degree;//(TVMaps.f[i]->count); int interiorIndex = copyPasteBuffer.faceData[copyIndex]->vecs->interiors[iid]; if ((interiorIndex >= 0) && (vertexLookUpList[interiorIndex] == -1)) { Point3 p = copyPasteBuffer.tVertData[interiorIndex]; ld->AddTVInterior(t,p, i, j,this,FALSE); vertexLookUpList[interiorIndex] = ld->GetFaceTVInterior(i,j);//TVMaps.f[i]->vecs->handles[j]; } else ld->SetFaceTVInterior(i,j,vertexLookUpList[interiorIndex]);//TVMaps.f[i]->vecs->interiors[j] = vertexLookUpList[interiorIndex]; } } copyIndex++; if (copyIndex >= copyPasteBuffer.faceData.Count()) copyIndex = 0; } } } } } ld->SetTVEdgeInvalid();//RebuildEdges(); if ( ip && (ip->GetSubObjectLevel() == 0) ) { if (fnGetTVSubMode() == TVVERTMODE) { BitArray fsel = ld->GetFaceSelection(); BitArray vsel = ld->GetTVVertSelection(); BitArray holdFSel(fsel); fsel = subFaceSel; ld->GetVertSelFromFace(vsel); ld->SetTVVertSelection(vsel); ld->SetFaceSelection(holdFSel);//fsel = holdFSel; } else if (fnGetTVSubMode() == TVEDGEMODE) { BitArray fsel = ld->GetFaceSelection(); BitArray esel = ld->GetTVEdgeSelection(); BitArray holdFSel(fsel); fsel = subFaceSel; ld->GetVertSelFromFace(fsel); ld->SetFaceSelection(fsel);// ld->GetEdgeSelFromVert(esel,FALSE); ld->SetTVEdgeSelection(esel); ld->SetFaceSelection(holdFSel);//fsel = holdFSel; } else if (fnGetTVSubMode() == TVFACEMODE) { ld->SetFaceSelection(subFaceSel);//fsel = subFaceSel; } } else { // md->faceSel = holdFaceSel; ld->SetFaceSelection(subFaceSel); /* if (fnGetTVSubMode() == TVFACEMODE) { ld->SetFaceSelection(subFaceSel);//fsel = subFaceSel; } */ } } CleanUpDeadVertices(); theHold.Accept(GetString(IDS_PW_PASTE)); NotifyDependents(FOREVER,PART_ALL,REFMSG_CHANGE); InvalidateView(); GetCOREInterface()->RedrawViews(GetCOREInterface()->GetTime()); }
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); }
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(); }