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::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 TweakMode::ExitMode() { mod->GetUIManager()->UpdateCheckButtons(); for (int ldID = 0; ldID < mod->GetMeshTopoDataCount(); ldID++) { MeshTopoData *ld = mod->GetMeshTopoData(ldID); ld->PostIntersect(); } }
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); } }
int TweakMouseProc::proc( HWND hwnd, int msg, int point, int flags, IPoint2 m ) { int res = TRUE; ViewExp& vpt = iObjParams->GetViewExp(hwnd); if ( ! vpt.IsAlive() ) { // why are we here DbgAssert(!_T("Invalid viewport!")); return FALSE; } static IPoint2 cancelPoints[3]; static HWND cancelHWND; switch ( msg ) { case MOUSE_PROPCLICK: //reset start point //kill the command mode SetCursor(LoadCursor(NULL,IDC_ARROW)); GetCOREInterface()->SetStdCommandMode(CID_OBJSELECT); mHitLD = NULL; break; case MOUSE_ABORT: { theHold.Cancel(); if (mHitLD) { mHitLD->SetTVVert(GetCOREInterface()->GetTime(),mHitTVVert,mSourceUVW,mod); mod->NotifyDependents(FOREVER, PART_TEXMAP, REFMSG_CHANGE); mod->InvalidateView(); if (mod->ip) mod->ip->RedrawViews(mod->ip->GetTime()); } break; } case MOUSE_POINT: { //see if we hit a point if (point == 0) { theHold.Begin(); mod->HoldPoints(); mHitLD = HitTest(vpt, m, mHitVert); if (mHitLD != NULL) { float at = 0; Ray r; vpt.MapScreenToWorldRay ((float) m.x, (float) m.y, r); TimeValue t = GetCOREInterface()->GetTime(); Matrix3 tm = mod->GetMeshTopoDataNode(mHitLDIndex)->GetObjectTM(t); Matrix3 itm = Inverse(tm); r.p = r.p * itm; r.dir = VectorTransform(r.dir,itm); mHitLD->Intersect(r,true,false, at, mBary, mHitFace); if (mHitFace != -1) { int deg = mHitLD->GetFaceDegree(mHitFace); for (int j = 0; j < deg; j++) { if (mHitVert == mHitLD->GetFaceGeomVert(mHitFace,j)) { mHitTVVert = mHitLD->GetFaceTVVert(mHitFace,j); mSourceUVW = mHitLD->GetTVVert(mHitTVVert); int offset1 = j; int offset2 = j+1; if (j == 0) { offset1 = 1; offset2 = 2; } else if (j == deg-1) { offset1 = deg-1; offset2 = deg-2; } mHitP[0] = mHitLD->GetGeomVert(mHitLD->GetFaceGeomVert(mHitFace,0)); mHitP[1] = mHitLD->GetGeomVert(mHitLD->GetFaceGeomVert(mHitFace,offset1)); mHitP[2] = mHitLD->GetGeomVert(mHitLD->GetFaceGeomVert(mHitFace,offset2)); mHitUVW[0] = mHitLD->GetTVVert(mHitLD->GetFaceTVVert(mHitFace,0)); mHitUVW[1] = mHitLD->GetTVVert(mHitLD->GetFaceTVVert(mHitFace,offset1)); mHitUVW[2] = mHitLD->GetTVVert(mHitLD->GetFaceTVVert(mHitFace,offset2)); } } } else { mHitLD->Intersect(r,true,false, at, mBary, mHitFace); mHitLD = NULL; } } } else { //accept the undo if (mHitLD) { if (flags & MOUSE_SHIFT) { AverageUVW(); } else { ComputeNewUVW(vpt, m); } mHitLD = NULL; TSTR mstr = mod->GetMacroStr(_T("modifiers[#unwrap_uvw].unwrap.setVertexPositionByNode")); macroRecorder->FunctionCall(mstr, 4, 0, mr_time,GetCOREInterface()->GetTime(), mr_int,mHitTVVert+1, mr_point3, mFinalUVW, mr_reftarg, mod->GetMeshTopoDataNode(mHitLDIndex) ); } theHold.Accept(GetString (IDS_DS_MOVE2)); } break; } case MOUSE_MOVE: { //if we hit a point get the transform and compute the uv offset if (mHitLD) { if (flags & MOUSE_SHIFT) { AverageUVW(); } else { ComputeNewUVW(vpt, m); } } break; } case MOUSE_FREEMOVE: { //see if hit and set cursor //hit test point int index = -1; float at = 0; Ray r; vpt.MapScreenToWorldRay ((float) m.x, (float) m.y, r); TimeValue t = GetCOREInterface()->GetTime(); BOOL hitFace = FALSE; for (int ldID = 0; ldID < mod->GetMeshTopoDataCount(); ldID++) { Matrix3 tm = mod->GetMeshTopoDataNode(ldID)->GetObjectTM(t); Matrix3 itm = Inverse(tm); r.p = r.p * itm; r.dir = VectorTransform(r.dir,itm); MeshTopoData *ld = mod->GetMeshTopoData(ldID); Point3 bry; int hit = -1; if (ld) { if (ld->Intersect(r,true,false, at, bry, hit)) hitFace = TRUE; } } if ((HitTest(vpt, m, index)!= NULL) && hitFace) SetCursor(GetCOREInterface()->GetSysCursor(SYSCUR_SELECT)); else SetCursor(LoadCursor(NULL,IDC_ARROW)); break; } } return res; }
unsigned __stdcall CallRelaxThread(void *data) { MaxSDK::Util::UseLanguagePackLocale(); RelaxThreadData *threadData = (RelaxThreadData *) data; threadData->mLocalData.SetCount( threadData->mod->GetMeshTopoDataCount()); for (int i = 0; i < threadData->mod->GetMeshTopoDataCount(); i++) threadData->mLocalData[i] = threadData->mod->GetMeshTopoData(i); threadData->mStarted = TRUE; DisableAccelerators(); BOOL rigSelected = FALSE; MeshTopoData *peltLD = threadData->mod->peltData.mBaseMeshTopoDataCurrent; if (threadData->mod->peltData.peltDialog.hWnd) { if (peltLD) { for (int i = 0; i < threadData->mod->peltData.rigPoints.Count(); i++) { int index = threadData->mod->peltData.rigPoints[i].lookupIndex; if (peltLD->GetTVVertSelected(index)) rigSelected = TRUE; } } } GetCOREInterface()->DisableSceneRedraw(); //if we are not instanced we can just start up unwrap relax and go if ((threadData->mod->GetMeshTopoDataCount() == 1) && !rigSelected) { if (threadData->mType == 0) threadData->mod->fnRelaxByFaceAngle(threadData->mIterations,threadData->mStretch,threadData->mAmount,threadData->mBoundary,NULL); else if (threadData->mType == 1) threadData->mod->fnRelaxByEdgeAngle(threadData->mIterations,threadData->mStretch,threadData->mAmount,threadData->mBoundary,NULL); else if (threadData->mType == 2) threadData->mod->RelaxVerts2(threadData->mAmount,threadData->mIterations,threadData->mBoundary,threadData->mCorner,FALSE); } //if we have multiple instance it gets more complicated //since only the first relax instance will ever run else { BOOL done = FALSE; threadData->mIterations = 5; for (int ldID = 0; ldID < threadData->mLocalData.Count(); ldID++) { threadData->mLocalData[ldID]->SetUserCancel(FALSE); } while(!done) { for (int ldID = 0; ldID < threadData->mLocalData.Count(); ldID++) { if (threadData->mLocalData[ldID]->GetUserCancel()) done = TRUE; } if (threadData->mType == 0) threadData->mod->fnRelaxByFaceAngle(threadData->mIterations,threadData->mStretch,threadData->mAmount,threadData->mBoundary,NULL); else if (threadData->mType == 1) threadData->mod->fnRelaxByEdgeAngle(threadData->mIterations,threadData->mStretch,threadData->mAmount,threadData->mBoundary,NULL); else if (threadData->mType == 2) threadData->mod->RelaxVerts2(threadData->mAmount,threadData->mIterations,threadData->mBoundary,threadData->mCorner,FALSE); if (rigSelected) threadData->mod->peltData.RelaxRig(threadData->mIterations,threadData->mAmount,threadData->mBoundary,threadData->mod); } } for (int ldID = 0; ldID < threadData->mod->GetMeshTopoDataCount(); ldID++) { threadData->mod->GetMeshTopoData(ldID)->SetUserCancel(FALSE); } GetCOREInterface()->EnableSceneRedraw(); EnableAccelerators(); threadData->mStarted = FALSE; ICustButton *iButton = GetICustButton(GetDlgItem(threadData->mod->relaxHWND, IDC_RUN_BUTTON)); if (iButton) { if (iButton->IsChecked()) { iButton->SetText(GetString(IDS_SPLINEMAP_STARTRELAX)); iButton->SetCheck(FALSE); } ReleaseICustButton(iButton); } _endthreadex(0); return 0; }
void UnwrapMod::fnGizmoCenter() { //get our tm //set the tm scale TimeValue t = GetCOREInterface()->GetTime(); //get our selection Box3 bounds; bounds.Init(); //get the bounding box Point3 pnorm(0.0f,0.0f,0.0f); int ct = 0; 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 * tm; if (j < 4) temp_point[j] = ld->GetGeomVert(index) * tm; //gverts.d[index].p; } pnorm += Normalize(temp_point[1]-temp_point[0]^temp_point[2]-temp_point[1]); ct++; } } } if (ct == 0) return; theHold.Begin(); SuspendAnimate(); AnimateOff(); pnorm = pnorm / (float) ct;//gfaces.Count(); //if just a primary axis set the tm; Point3 center = bounds.Center(); // build the scale //get our tm Matrix3 tm(1); tm = *fnGetGizmoTM(); Matrix3 initialTM = tm; Point3 vec2; vec2 = Normalize(tm.GetRow(0)); tm.SetRow(0,vec2); vec2 = Normalize(tm.GetRow(1)) ; tm.SetRow(1,vec2); vec2 = Normalize(tm.GetRow(2)); tm.SetRow(2,vec2); tm.SetRow(3,center); Matrix3 itm = Inverse(tm); //find our x and y scale 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 * tm * itm; localBounds += p; // if (fabs(p.x) > xmax) xmax = fabs(p.x); // if (fabs(p.y) > ymax) ymax = fabs(p.y); // if (fabs(p.z) > zmax) zmax = fabs(p.z); } } } } if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP)) center = localBounds.Center() * tm; else if (fnGetMapMode() == CYLINDRICALMAP) { Point3 zvec = initialTM.GetRow(2); // center = center * tm; center = localBounds.Center() * tm - (zvec * 0.5f); } initialTM.SetRow(3,center); Matrix3 ptm(1), id(1); initialTM = initialTM ; SetXFormPacket tmpck(initialTM,ptm); tmControl->SetValue(t,&tmpck,TRUE,CTRL_RELATIVE); ResumeAnimate(); if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == CYLINDRICALMAP) || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP)) ApplyGizmo(); theHold.Accept(GetString(IDS_MAPPING_FIT)); fnGetGizmoTM(); if (ip) ip->RedrawViews(ip->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::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::ApplyGizmoPrivate(Matrix3 *defaultTM) { BOOL wasHolding = FALSE; if (theHold.Holding()) wasHolding = TRUE; if (!theHold.Holding()) { theHold.Begin(); } HoldPointsAndFaces(); //add vertices to our internal vertex list filling in dead spots where appropriate //get align normal //get fit data Matrix3 gtm(1); TimeValue t = 0; if (ip) t = ip->GetTime(); if (defaultTM) gtm = *defaultTM; else { if (tmControl) { gtm = GetMapGizmoMatrix(t); if (!fnGetNormalizeMap()) { for (int i = 0; i < 3; i++) { Point3 vec = gtm.GetRow(i); vec = Normalize(vec); gtm.SetRow(i,vec); } } } } for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++) { MeshTopoData *ld = mMeshTopoData[ldID]; Matrix3 tm(1); tm = mMeshTopoData.GetNodeTM(t,ldID)* Inverse(gtm); ld->ApplyMap(fnGetMapMode(), fnGetNormalizeMap(), tm, this); ld->SetTVEdgeInvalid(); ld->BuildTVEdges(); ld->BuildVertexClusterList(); } if (!wasHolding) { theHold.Accept(GetString(IDS_PW_PLANARMAP)); } RebuildEdges(); theHold.Suspend(); fnFaceToEdgeSelect(); theHold.Resume(); // ConvertFaceToEdgeSel(); // TVMaps.edgesValid= FALSE; //update our views to show new faces InvalidateView(); }
void UnwrapMod::ApplyGizmo() { if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == PELTMAP) || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == CYLINDRICALMAP)) { ApplyGizmoPrivate(); } else { theHold.Begin(); //compute the center //get our normal list for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++) { MeshTopoData *ld = mMeshTopoData[ldID]; ld->HoldFaceSel(); } for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++) { MeshTopoData *ld = mMeshTopoData[ldID]; ld->HoldFaceSel(); Tab<Point3> fnorms; fnorms.SetCount(ld->GetNumberFaces()); for (int k=0; k< fnorms.Count(); k++) fnorms[k] = Point3(0.0f,0.0f,0.0f); //get our projection normal Point3 projectionNorm(0.0f,0.0f,0.0f); //build normals for (int k = 0; k < fnorms.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]; if (j < 4) temp_point[j] = ld->GetGeomVert(index);//gverts.d[index].p; } fnorms[k] = Normalize(temp_point[1]-temp_point[0]^temp_point[2]-temp_point[1]); } } BitArray front,back,left,right,top,bottom; front.SetSize(ld->GetNumberFaces()); front.ClearAll(); back = front; left = front; right = front; top = front; bottom = front; Tab<Point3> norms; Matrix3 gtm(1); TimeValue t = 0; if (ip) t = ip->GetTime(); if (tmControl) tmControl->GetValue(t,>m,FOREVER,CTRL_RELATIVE); norms.SetCount(6); for (int i = 0; i < 3; i++) { Point3 v = gtm.GetRow(i); norms[i*2] = Normalize(v); norms[i*2+1] = norms[i*2] * -1.0f; } for (int k=0; k< ld->GetNumberFaces(); k++) { if (ld->GetFaceSelected(k)) { int closestFace = -1; float closestAngle = -10.0f; for (int j = 0; j < 6; j++) { float dot = DotProd(norms[j],fnorms[k]); if (dot > closestAngle) { closestAngle = dot; closestFace = j; } } if (closestFace == 0) front.Set(k,TRUE); else if (closestFace == 1) back.Set(k,TRUE); else if (closestFace == 2) left.Set(k,TRUE); else if (closestFace == 3) right.Set(k,TRUE); else if (closestFace == 4) top.Set(k,TRUE); else if (closestFace == 5) bottom.Set(k,TRUE); } } gtm.IdentityMatrix(); if (tmControl) tmControl->GetValue(t,>m,FOREVER,CTRL_RELATIVE); Point3 xvec,yvec,zvec; xvec = gtm.GetRow(0); yvec = gtm.GetRow(1); zvec = gtm.GetRow(2); Point3 center = gtm.GetRow(3); for (int k = 0; k < 6; k++) { Matrix3 tm(1); if (k == 0) { tm.SetRow(0,yvec); tm.SetRow(1,zvec); tm.SetRow(2,xvec); ld->SetFaceSelection(front); } else if (k == 1) { tm.SetRow(0,yvec); tm.SetRow(1,zvec); tm.SetRow(2,(xvec*-1.0f)); ld->SetFaceSelection(back); } else if (k == 2) { tm.SetRow(0,xvec); tm.SetRow(1,zvec); tm.SetRow(2,yvec); ld->SetFaceSelection(left); } else if (k == 3) { tm.SetRow(0,xvec); tm.SetRow(1,zvec); tm.SetRow(2,(yvec *-1.0f)); ld->SetFaceSelection(right); } else if (k == 4) { tm.SetRow(0,xvec); tm.SetRow(1,yvec); tm.SetRow(2,zvec); ld->SetFaceSelection(top); } else if (k == 5) { tm.SetRow(0,xvec); tm.SetRow(1,yvec); tm.SetRow(2,(zvec*-1.0f)); ld->SetFaceSelection(bottom); } tm.SetRow(3,center); if (!fnGetNormalizeMap()) { for (int i = 0; i < 3; i++) { Point3 vec = tm.GetRow(i); vec = Normalize(vec); tm.SetRow(i,vec); } } tm = mMeshTopoData.GetNodeTM(t,ldID) * Inverse(tm); ld->ApplyMap(fnGetMapMode(), fnGetNormalizeMap(), tm, this); } ld->RestoreFaceSel(); } theHold.Accept(GetString(IDS_PW_PLANARMAP)); } }
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::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::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); }
void UnwrapMod::fnGizmoReset() { theHold.Begin(); SuspendAnimate(); AnimateOff(); TimeValue t = GetCOREInterface()->GetTime(); //get our selection Box3 bounds; bounds.Init(); //get the bounding box 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++)//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]; bounds += ld->GetGeomVert(index) * tm;//gverts.d[index].p; } } } } 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; float scl = scale.x; if (scale.y > scl) scl = scale.y; if (scale.z > scl) scl = scale.z; scale.x = scl; scale.y = scl; scale.z = scl; 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)) 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); ResumeAnimate(); if ((fnGetMapMode() == PLANARMAP) || (fnGetMapMode() == CYLINDRICALMAP) || (fnGetMapMode() == SPHERICALMAP) || (fnGetMapMode() == BOXMAP)) ApplyGizmo(); theHold.Accept(GetString(IDS_MAPPING_RESET)); fnGetGizmoTM(); if (ip) ip->RedrawViews(ip->GetTime()); }
void UnwrapMod::RebuildEdges() { if (mode == ID_SKETCHMODE) SetMode(ID_MOVE); for (int ldID = 0; ldID < mMeshTopoData.Count(); ldID++) { MeshTopoData *ld = mMeshTopoData[ldID]; ld->SetTVEdgeInvalid(); ld->SetGeoEdgeInvalid(); ld->BuildTVEdges(); ld->BuildVertexClusterList(); } /* BitArray holdVSel(vsel); BOOL holdSyncMode = fnGetSyncSelectionMode(); fnSetSyncSelectionMode(FALSE); TVMaps.BuildEdges( ); //PELT TVMaps.BuildGeomEdges( ); if (esel.GetSize() != TVMaps.ePtrList.Count()) { esel.SetSize(TVMaps.ePtrList.Count()); esel.ClearAll(); } if (gesel.GetSize() != TVMaps.gePtrList.Count()) { gesel.SetSize(TVMaps.gePtrList.Count()); gesel.ClearAll(); } //FP 05/26/06 : PELT Mapping - CER Bucket #370291 //When the topology of the object changes, the seams bits array need to be updated. //By clearing it there, the update will be done each time the topology changes if (peltData.seamEdges.GetSize() != TVMaps.gePtrList.Count()) { peltData.seamEdges.SetSize(TVMaps.gePtrList.Count()); peltData.seamEdges.ClearAll(); } vsel = holdVSel; fnSetSyncSelectionMode(holdSyncMode); usedVertices.SetSize(TVMaps.v.Count()); usedVertices.ClearAll(); for (int i = 0; i < TVMaps.f.Count(); i++) { int faceIndex = i; for (int k = 0; k < TVMaps.f[faceIndex]->count; k++) { if (!(TVMaps.f[faceIndex]->flags & FLAG_DEAD)) { int vertIndex = TVMaps.f[faceIndex]->t[k]; usedVertices.Set(vertIndex); if (objType == IS_PATCH) { if ((TVMaps.f[faceIndex]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[faceIndex]->vecs)) { if (TVMaps.f[faceIndex]->flags & FLAG_INTERIOR) { vertIndex = TVMaps.f[faceIndex]->vecs->interiors[k]; if ((vertIndex >=0) && (vertIndex < usedVertices.GetSize())) usedVertices.Set(vertIndex); } vertIndex = TVMaps.f[faceIndex]->vecs->handles[k*2]; if ((vertIndex >=0) && (vertIndex < usedVertices.GetSize())) usedVertices.Set(vertIndex); vertIndex = TVMaps.f[faceIndex]->vecs->handles[k*2+1]; if ((vertIndex >=0) && (vertIndex < usedVertices.GetSize())) usedVertices.Set(vertIndex); } } } } } //PELT for (int i = 0; i < peltData.springEdges.Count(); i++) { int vertIndex = peltData.springEdges[i].v1; if (vertIndex != -1) usedVertices.Set(vertIndex); vertIndex = peltData.springEdges[i].v2; if (vertIndex != -1) usedVertices.Set(vertIndex); vertIndex = peltData.springEdges[i].vec1; if ( (vertIndex != -1) && (vertIndex < usedVertices.GetSize())) usedVertices.Set(vertIndex); vertIndex = peltData.springEdges[i].vec2; if ( (vertIndex != -1) && (vertIndex < usedVertices.GetSize())) usedVertices.Set(vertIndex); } BuildEdgeDistortionData(); */ }
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(); }