void MeshTopoData::SetCache(PatchMesh &patch, int mapChannel) { FreeCache(); this->patch = new PatchMesh(patch); //build TVMAP and edge data mFSelPrevious.SetSize(patch.patchSel.GetSize()); mFSelPrevious = patch.patchSel; if ( (patch.selLevel==PATCH_PATCH) && (patch.patchSel.NumberSet() == 0) ) { TVMaps.SetCountFaces(0); TVMaps.v.SetCount(0); TVMaps.FreeEdges(); TVMaps.FreeGeomEdges(); mVSel.SetSize(0); mESel.SetSize(0); mFSel.SetSize(0); mGESel.SetSize(0); mGVSel.SetSize(0); return; } //loop through all maps //get channel from mesh TVMaps.channel = mapChannel; //get from mesh based on cahne PatchTVert *tVerts = NULL; TVPatch *tvFace = NULL; if (!patch.getMapSupport(mapChannel)) { patch.setNumMaps(mapChannel+1); } tVerts = patch.tVerts[mapChannel]; tvFace = patch.tvPatches[mapChannel]; if (patch.selLevel!=PATCH_PATCH ) { //copy into our structs TVMaps.SetCountFaces(patch.getNumPatches()); TVMaps.v.SetCount(patch.getNumMapVerts(mapChannel)); mVSel.SetSize(patch.getNumMapVerts (mapChannel)); TVMaps.geomPoints.SetCount(patch.getNumVerts()+patch.getNumVecs()); for (int j=0; j<TVMaps.f.Count(); j++) { TVMaps.f[j]->flags = 0; int pcount = 3; if (patch.patches[j].type == PATCH_QUAD) { pcount = 4; } TVMaps.f[j]->t = new int[pcount]; TVMaps.f[j]->v = new int[pcount]; if (tvFace == NULL) { TVMaps.f[j]->t[0] = 0; TVMaps.f[j]->t[1] = 0; TVMaps.f[j]->t[2] = 0; if (pcount ==4) TVMaps.f[j]->t[3] = 0; TVMaps.f[j]->FaceIndex = j; TVMaps.f[j]->MatID = patch.getPatchMtlIndex(j); TVMaps.f[j]->flags = 0; TVMaps.f[j]->count = pcount; TVMaps.f[j]->vecs = NULL; UVW_TVVectorClass *tempv = NULL; //new an instance if (!(patch.patches[j].flags & PATCH_AUTO)) TVMaps.f[j]->flags |= FLAG_INTERIOR; if (!(patch.patches[j].flags & PATCH_LINEARMAPPING)) { tempv = new UVW_TVVectorClass(); TVMaps.f[j]->flags |= FLAG_CURVEDMAPPING; } TVMaps.f[j]->vecs = tempv; for (int k = 0; k < pcount; k++) { int index = patch.patches[j].v[k]; TVMaps.f[j]->v[k] = index; TVMaps.geomPoints[index] = patch.verts[index].p; //do handles and interiors //check if linear if (!(patch.patches[j].flags & PATCH_LINEARMAPPING)) { //do geometric points index = patch.patches[j].interior[k]; TVMaps.f[j]->vecs->vinteriors[k] =patch.getNumVerts()+index; index = patch.patches[j].vec[k*2]; TVMaps.f[j]->vecs->vhandles[k*2] =patch.getNumVerts()+index; index = patch.patches[j].vec[k*2+1]; TVMaps.f[j]->vecs->vhandles[k*2+1] =patch.getNumVerts()+index; // do texture points do't need to since they don't exist in this case TVMaps.f[j]->vecs->interiors[k] =0; TVMaps.f[j]->vecs->handles[k*2] =0; TVMaps.f[j]->vecs->handles[k*2+1] =0; } } } else { TVMaps.f[j]->t[0] = tvFace[j].tv[0]; TVMaps.f[j]->t[1] = tvFace[j].tv[1]; TVMaps.f[j]->t[2] = tvFace[j].tv[2]; if (pcount ==4) TVMaps.f[j]->t[3] = tvFace[j].tv[3]; TVMaps.f[j]->FaceIndex = j; TVMaps.f[j]->MatID = patch.getPatchMtlIndex(j); TVMaps.f[j]->flags = 0; TVMaps.f[j]->count = pcount; TVMaps.f[j]->vecs = NULL; UVW_TVVectorClass *tempv = NULL; if (!(patch.patches[j].flags & PATCH_AUTO)) TVMaps.f[j]->flags |= FLAG_INTERIOR; //new an instance if (!(patch.patches[j].flags & PATCH_LINEARMAPPING)) { BOOL mapLinear = FALSE; for (int tvCount = 0; tvCount < patch.patches[j].type*2; tvCount++) { if (tvFace[j].handles[tvCount] < 0) mapLinear = TRUE; } if (!(patch.patches[j].flags & PATCH_AUTO)) { for (int tvCount = 0; tvCount < patch.patches[j].type; tvCount++) { if (tvFace[j].interiors[tvCount] < 0) mapLinear = TRUE; } } if (!mapLinear) { tempv = new UVW_TVVectorClass(); TVMaps.f[j]->flags |= FLAG_CURVEDMAPPING; } } TVMaps.f[j]->vecs = tempv; if ((patch.selLevel==PATCH_PATCH ) && (patch.patchSel[j] == 0)) TVMaps.f[j]->flags |= FLAG_DEAD; for (int k = 0; k < pcount; k++) { int index = patch.patches[j].v[k]; TVMaps.f[j]->v[k] = index; TVMaps.geomPoints[index] = patch.verts[index].p; // TVMaps.f[j].pt[k] = patch.verts[index].p; //do handles and interiors //check if linear if (TVMaps.f[j]->flags & FLAG_CURVEDMAPPING) { //do geometric points index = patch.patches[j].interior[k]; TVMaps.f[j]->vecs->vinteriors[k] =patch.getNumVerts()+index; index = patch.patches[j].vec[k*2]; TVMaps.f[j]->vecs->vhandles[k*2] =patch.getNumVerts()+index; index = patch.patches[j].vec[k*2+1]; TVMaps.f[j]->vecs->vhandles[k*2+1] =patch.getNumVerts()+index; // do texture points do't need to since they don't exist in this case if (TVMaps.f[j]->flags & FLAG_INTERIOR) { index = tvFace[j].interiors[k]; TVMaps.f[j]->vecs->interiors[k] =index; } index = tvFace[j].handles[k*2]; TVMaps.f[j]->vecs->handles[k*2] =index; index = tvFace[j].handles[k*2+1]; TVMaps.f[j]->vecs->handles[k*2+1] =index; } } } } for (int geomvecs =0; geomvecs < patch.getNumVecs(); geomvecs++) { TVMaps.geomPoints[geomvecs+patch.getNumVerts()] = patch.vecs[geomvecs].p; } for ( int j=0; j<TVMaps.v.Count(); j++) { TVMaps.v[j].SetFlag(0); if (tVerts) TVMaps.v[j].SetP(tVerts[j]); else TVMaps.v[j].SetP(Point3(0.0f,0.0f,0.0f)); TVMaps.v[j].SetInfluence(0.0f); TVMaps.v[j].SetControlID(-1); } if (tvFace == NULL) BuildInitialMapping(&patch); TVMaps.mSystemLockedFlag.SetSize(TVMaps.v.Count()); TVMaps.mSystemLockedFlag.ClearAll(); } else { //copy into our structs TVMaps.SetCountFaces(patch.getNumPatches()); TVMaps.v.SetCount(patch.getNumMapVerts (mapChannel)); mVSel.SetSize(patch.getNumMapVerts (mapChannel)); TVMaps.geomPoints.SetCount(patch.getNumVerts()+patch.getNumVecs()); for (int j=0; j<TVMaps.f.Count(); j++) { TVMaps.f[j]->flags = 0; int pcount = 3; if (patch.patches[j].type == PATCH_QUAD) { pcount = 4; } TVMaps.f[j]->t = new int[pcount]; TVMaps.f[j]->v = new int[pcount]; if (tvFace == NULL) { TVMaps.f[j]->t[0] = 0; TVMaps.f[j]->t[1] = 0; TVMaps.f[j]->t[2] = 0; if (pcount == 4) TVMaps.f[j]->t[3] = 0; TVMaps.f[j]->FaceIndex = j; TVMaps.f[j]->MatID = patch.patches[j].getMatID(); if (patch.patchSel[j]) TVMaps.f[j]->flags = 0; else TVMaps.f[j]->flags = FLAG_DEAD; TVMaps.f[j]->count = pcount; TVMaps.f[j]->vecs = NULL; UVW_TVVectorClass *tempv = NULL; if (!(patch.patches[j].flags & PATCH_AUTO)) TVMaps.f[j]->flags |= FLAG_INTERIOR; //new an instance if (!(patch.patches[j].flags & PATCH_LINEARMAPPING)) { tempv = new UVW_TVVectorClass(); TVMaps.f[j]->flags |= FLAG_CURVEDMAPPING; } TVMaps.f[j]->vecs = tempv; for (int k = 0; k < pcount; k++) { int index = patch.patches[j].v[k]; TVMaps.f[j]->v[k] = index; TVMaps.geomPoints[index] = patch.verts[index].p; // TVMaps.f[j].pt[k] = patch.verts[index].p; //check if linear if (!(patch.patches[j].flags & PATCH_LINEARMAPPING)) { //do geometric points index = patch.patches[j].interior[k]; TVMaps.f[j]->vecs->vinteriors[k] =patch.getNumVerts()+index; index = patch.patches[j].vec[k*2]; TVMaps.f[j]->vecs->vhandles[k*2] =patch.getNumVerts()+index; index = patch.patches[j].vec[k*2+1]; TVMaps.f[j]->vecs->vhandles[k*2+1] =patch.getNumVerts()+index; // do texture points do't need to since they don't exist in this case TVMaps.f[j]->vecs->interiors[k] =0; TVMaps.f[j]->vecs->handles[k*2] =0; TVMaps.f[j]->vecs->handles[k*2+1] =0; } } } else { TVMaps.f[j]->t[0] = tvFace[j].tv[0]; TVMaps.f[j]->t[1] = tvFace[j].tv[1]; TVMaps.f[j]->t[2] = tvFace[j].tv[2]; if (pcount == 4) TVMaps.f[j]->t[3] = tvFace[j].tv[3]; TVMaps.f[j]->FaceIndex = j; TVMaps.f[j]->MatID = patch.patches[j].getMatID(); if (patch.patchSel[j]) TVMaps.f[j]->flags = 0; else TVMaps.f[j]->flags = FLAG_DEAD; int pcount = 3; if (patch.patches[j].type == PATCH_QUAD) { pcount = 4; } TVMaps.f[j]->count = pcount; TVMaps.f[j]->vecs = NULL; UVW_TVVectorClass *tempv = NULL; if (!(patch.patches[j].flags & PATCH_AUTO)) TVMaps.f[j]->flags |= FLAG_INTERIOR; //new an instance if (!(patch.patches[j].flags & PATCH_LINEARMAPPING)) { BOOL mapLinear = FALSE; for (int tvCount = 0; tvCount < patch.patches[j].type*2; tvCount++) { if (tvFace[j].handles[tvCount] < 0) mapLinear = TRUE; } if (!(patch.patches[j].flags & PATCH_AUTO)) { for (int tvCount = 0; tvCount < patch.patches[j].type; tvCount++) { if (tvFace[j].interiors[tvCount] < 0) mapLinear = TRUE; } } if (!mapLinear) { tempv = new UVW_TVVectorClass(); TVMaps.f[j]->flags |= FLAG_CURVEDMAPPING; } } TVMaps.f[j]->vecs = tempv; for (int k = 0; k < pcount; k++) { int index = patch.patches[j].v[k]; TVMaps.f[j]->v[k] = index; TVMaps.geomPoints[index] = patch.verts[index].p; // TVMaps.f[j].pt[k] = patch.verts[index].p; //do handles and interiors //check if linear if (TVMaps.f[j]->flags & FLAG_CURVEDMAPPING) { //do geometric points index = patch.patches[j].interior[k]; TVMaps.f[j]->vecs->vinteriors[k] =patch.getNumVerts()+index; index = patch.patches[j].vec[k*2]; TVMaps.f[j]->vecs->vhandles[k*2] =patch.getNumVerts()+index; index = patch.patches[j].vec[k*2+1]; TVMaps.f[j]->vecs->vhandles[k*2+1] =patch.getNumVerts()+index; // do texture points do't need to since they don't exist in this case if (TVMaps.f[j]->flags & FLAG_INTERIOR) { index = tvFace[j].interiors[k]; TVMaps.f[j]->vecs->interiors[k] =index; } index = tvFace[j].handles[k*2]; TVMaps.f[j]->vecs->handles[k*2] =index; index = tvFace[j].handles[k*2+1]; TVMaps.f[j]->vecs->handles[k*2+1] =index; } } } } for (int j =0; j < patch.getNumVecs(); j++) { TVMaps.geomPoints[j+patch.getNumVerts()] = patch.vecs[j].p; } for (int j=0; j<TVMaps.v.Count(); j++) { // TVMaps.v[j].SystemLocked(TRUE); if (tVerts) TVMaps.v[j].SetP(tVerts[j]); else TVMaps.v[j].SetP(Point3(.0f,0.0f,0.0f)); //check if vertex for this face selected TVMaps.v[j].SetInfluence(0.0f); TVMaps.v[j].SetControlID(-1); } if (tvFace == NULL) BuildInitialMapping(&patch); TVMaps.mSystemLockedFlag.SetSize(TVMaps.v.Count()); TVMaps.mSystemLockedFlag.SetAll(); for (int j=0; j<TVMaps.f.Count(); j++) { if (!(TVMaps.f[j]->flags & FLAG_DEAD)) { int a; a = TVMaps.f[j]->t[0]; TVMaps.v[a].SetFlag(0); TVMaps.mSystemLockedFlag.Set(a,FALSE); a = TVMaps.f[j]->t[1]; TVMaps.v[a].SetFlag(0); TVMaps.mSystemLockedFlag.Set(a,FALSE); a = TVMaps.f[j]->t[2]; TVMaps.v[a].SetFlag(0); TVMaps.mSystemLockedFlag.Set(a,FALSE); if (TVMaps.f[j]->count > 3) { a = TVMaps.f[j]->t[3]; TVMaps.v[a].SetFlag(0); TVMaps.mSystemLockedFlag.Set(a,FALSE); } if ( (TVMaps.f[j]->flags & FLAG_CURVEDMAPPING) && (TVMaps.f[j]->vecs)) { for (int m =0; m < TVMaps.f[j]->count; m++) { int hid = TVMaps.f[j]->vecs->handles[m*2]; TVMaps.v[hid].SetFlag(0) ; TVMaps.mSystemLockedFlag.Set(hid,FALSE); hid = TVMaps.f[j]->vecs->handles[m*2+1]; TVMaps.v[hid].SetFlag(0) ; TVMaps.mSystemLockedFlag.Set(hid,FALSE); } if (TVMaps.f[j]->flags & FLAG_INTERIOR) { for (int m =0; m < TVMaps.f[j]->count; m++) { int iid = TVMaps.f[j]->vecs->interiors[m]; TVMaps.v[iid].SetFlag(0); TVMaps.mSystemLockedFlag.Set(iid,FALSE); } } } } } } }
// Edger Delete modifier method void EditPatchMod::DoEdgeDelete() { ModContextList mcList; INodeTab nodes; TimeValue t = ip->GetTime(); int holdNeeded = 0; if (!ip) return; ip->GetModContexts(mcList, nodes); ClearPatchDataFlag(mcList, EPD_BEENDONE); theHold.Begin(); RecordTopologyTags(); for (int i = 0; i < mcList.Count(); i++) { int altered = 0; EditPatchData *patchData =(EditPatchData*)mcList[i]->localData; if (!patchData) continue; if (patchData->GetFlag(EPD_BEENDONE)) continue; // If the mesh isn't yet cache, this will cause it to get cached. RPatchMesh *rpatch; PatchMesh *patch = patchData->TempData(this)->GetPatch(t, rpatch); if (!patch) continue; patchData->RecordTopologyTags(patch); // If this is the first edit, then the delta arrays will be allocated patchData->BeginEdit(t); // If any bits are set in the selection set, let's DO IT!! if (patch->edgeSel.NumberSet()) { altered = holdNeeded = 1; if (theHold.Holding()) theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "DoEdgeDelete")); int edges = patch->getNumEdges(); int patches = patch->getNumPatches(); int verts = patch->getNumVerts(); // Tag the patches that are attached to selected edges BitArray delPatches(patches); delPatches.ClearAll(); for (int i = 0; i < edges; ++i) { if (patch->edgeSel[i]) { #if (MAX_RELEASE < 4000) if (patch->edges[i].patch1 >= 0) delPatches.Set(patch->edges[i].patch1); if (patch->edges[i].patch2 >= 0) delPatches.Set(patch->edges[i].patch2); #else // (MAX_RELEASE < 4000) if (patch->edges[i].patches[0] >= 0) delPatches.Set(patch->edges[i].patches[0]); if (patch->edges[i].patches[1] >= 0) delPatches.Set(patch->edges[i].patches[1]); #endif // (MAX_RELEASE < 4000) } } BitArray delVerts(verts); delVerts.ClearAll(); DeletePatchParts(patch, rpatch, delVerts, delPatches); patch->computeInteriors(); patchData->UpdateChanges(patch, rpatch); patchData->TempData(this)->Invalidate(PART_TOPO); } patchData->SetFlag(EPD_BEENDONE, TRUE); } if (holdNeeded) { ResolveTopoChanges(); theHold.Accept(GetString(IDS_TH_EDGEDELETE)); } else { ip->DisplayTempPrompt(GetString(IDS_TH_NOEDGESSEL), PROMPT_TIME); theHold.End(); } nodes.DisposeTemporary(); ClearPatchDataFlag(mcList, EPD_BEENDONE); NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL); }