void EditPatchMod::ActivateSubSelSet(TSTR &setName) { MaybeFixupNamedSels(); ModContextList mcList; INodeTab nodes; int index = FindSet(setName, selLevel); if (index < 0 || !ip) return; ip->GetModContexts(mcList, nodes); theHold.Begin(); for (int i = 0; i < mcList.Count(); i++) { EditPatchData *patchData =(EditPatchData*)mcList[i]->localData; if (!patchData) continue; RPatchMesh *rpatch; PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch); if (!patch) continue; patchData->BeginEdit(ip->GetTime()); // If that set exists in this context, deal with it GenericNamedSelSetList &sel = patchData->GetSelSet(this); BitArray *set = sel.GetSet(setName); if (set) { if (theHold.Holding()) theHold.Put(new PatchSelRestore(patchData, this, patch)); BitArray *psel = GetLevelSelectionSet(patch, rpatch); // Get the appropriate selection set AssignSetMatchSize(*psel, *set); PatchSelChanged(); } patchData->UpdateChanges(patch, rpatch, FALSE); if (patchData->tempData) patchData->TempData(this)->Invalidate(PART_SELECT); } theHold.Accept(GetString(IDS_DS_SELECT)); nodes.DisposeTemporary(); NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime()); }
void EditFaceDataMod::InvertSelection(int selLevel) { ModContextList list; INodeTab nodes; ip->GetModContexts(list,nodes); EditFaceDataModData *d; for (int i=0; i<list.Count(); i++) { d = (EditFaceDataModData*)list[i]->localData; if (!d) continue; if (theHold.Holding() && !d->GetHeld()) theHold.Put(new SelectRestore(this,d)); d->SynchSize(); switch (selLevel) { case SEL_FACE: d->GetFaceSel() = ~d->GetFaceSel(); break; } } nodes.DisposeTemporary(); SelectionChanged (); }
bool SmoothingGroupUIHandler::GetSmoothingGroups (EPolyMod *pMod, DWORD *anyFaces, DWORD *allFaces, bool useSel) { bool ret = true; // Initialization: *anyFaces = 0; if (allFaces) *allFaces = ~0; bool useStackSelection = pMod->getParamBlock()->GetInt (epm_stack_selection) != 0; ModContextList list; INodeTab nodes; pMod->EpModGetIP()->GetModContexts (list, nodes); for (int i=0; i<list.Count(); i++) { EditPolyData *pData = (EditPolyData *) list[i]->localData; if (!pData) continue; MNMesh *pMesh = pData->GetMeshOutput(); if (!pMesh) { ret = false; continue; } DWORD l_selFlag = useStackSelection ? MN_EDITPOLY_STACK_SELECT:MN_SEL; for (int j=0; j<pMesh->numf; j++) { if (useSel && !pMesh->f[j].GetFlag (l_selFlag)) continue; if (pMesh->f[j].GetFlag (MN_DEAD)) continue; *anyFaces |= pMesh->f[j].smGroup; if (allFaces) *allFaces &= pMesh->f[j].smGroup; } } nodes.DisposeTemporary (); if (allFaces) *allFaces &= *anyFaces; return ret; }
INode *EditPolyMod::EpModGetPrimaryNode () { if (!ip) return NULL; ModContextList list; INodeTab nodes; ip->GetModContexts(list,nodes); INode *ret = NULL; for (int i=0; i<list.Count(); i++) { if (list[i]->localData == NULL) continue; EditPolyData *pData = (EditPolyData *) list[i]->localData; if (pData->GetFlag (kEPDataPrimary)) { ret = nodes[i]; break; } } if (!ret) { // No primary? Ok, return first one we get to (and make it primary). for (int i=0; i<list.Count(); i++) { if (list[i]->localData == NULL) continue; EditPolyData *pData = (EditPolyData *) list[i]->localData; pData->SetFlag (kEPDataPrimary); ret = nodes[i]; break; } } if (ret) ret = ret->GetActualINode (); nodes.DisposeTemporary(); return ret; }
void EditFaceDataMod::SelectSubComponent (HitRecord *hitRec, BOOL selected, BOOL all, BOOL invert) { EditFaceDataModData *d = NULL, *od = NULL; ModContextList mcList; INodeTab nodes; ip->GetModContexts(mcList,nodes); BitArray nsel; for (int nd=0; nd<mcList.Count(); nd++) { d = (EditFaceDataModData*) mcList[nd]->localData; if (d==NULL) continue; HitRecord *hr = hitRec; if (!all && (hr->modContext->localData != d)) continue; for (; hr!=NULL; hr=hr->Next()) if (hr->modContext->localData == d) break; if (hr==NULL) continue; Mesh *mesh = d->GetCacheMesh(); MNMesh *mnmesh = d->GetCacheMNMesh(); if (!mesh && !mnmesh) continue; if (theHold.Holding() && !d->GetHeld()) theHold.Put (new SelectRestore (this, d)); switch (selLevel) { case SEL_FACE: nsel = d->GetFaceSel(); for (; hr != NULL; hr=hr->Next()) { if (d != hr->modContext->localData) continue; nsel.Set (hr->hitInfo, invert ? !d->GetFaceSel()[hr->hitInfo] : selected); if (!all) break; } d->GetFaceSel() = nsel; break; } } nodes.DisposeTemporary (); SelectionChanged (); }
void VertexPaint::EndEditParams( IObjParam *ip, ULONG flags,Animatable *next) { // Dsiable Painting. bool lpm= _LastPaintMode; ActivatePaint(FALSE); // bkup lastPainMode _LastPaintMode= lpm; ReleaseISpinner (iTint); ReleaseISpinner (iGradientBend); ModContextList list; INodeTab nodes; ip->GetModContexts(list,nodes); for (int i=0; i<list.Count(); i++) { VertexPaintData *vd = (VertexPaintData*)list[i]->localData; if (vd) vd->FreeCache(); } nodes.DisposeTemporary(); // Reset show end result SetFlag (VP_DISP_END_RESULT, ip->GetShowEndResult() ? TRUE : FALSE); ip->SetShowEndResult(oldShowEnd); // Exit editMod => draw true colored weights. editMod = NULL; NotifyDependents(FOREVER, PART_VERTCOLOR, REFMSG_CHANGE); ip->DeleteRollupPage(hParams); hParams = NULL; iTint = NULL; iGradientBend= NULL; this->ip = NULL; }
// Selection set, misc fixup utility function // This depends on PatchMesh::RecordTopologyTags being called prior to the topo changes void EditPatchMod::ResolveTopoChanges() { ModContextList mcList; INodeTab nodes; TimeValue t = ip->GetTime(); ip->GetModContexts(mcList, nodes); ClearPatchDataFlag(mcList, EPD_BEENDONE); for (int i = 0; i < mcList.Count(); i++) { 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; // First, the vertex selections int set; for (set = 0; set < patchData->vselSet.Count(); ++set) { BitArray *oldVS = &patchData->vselSet[set]; BitArray newVS; newVS.SetSize(patch->numVerts); for (int vert = 0; vert < patch->numVerts; ++vert) { // Get the knot's previous location, then copy that selection into the new set int tag = patch->verts[vert].aux1; if (tag >= 0) newVS.Set(vert, (*oldVS)[tag]); else newVS.Clear(vert); } if (theHold.Holding()) theHold.Put(new ChangeNamedSetRestore(&patchData->vselSet, set, oldVS)); patchData->vselSet[set] = newVS; } // Now the edge selections for (set = 0; set < patchData->eselSet.Count(); ++set) { BitArray *oldES = &patchData->eselSet[set]; BitArray newES; newES.SetSize(patch->numEdges); for (int edge = 0; edge < patch->numEdges; ++edge) { // Get the knot's previous location, then copy that selection into the new set int tag = patch->edges[edge].aux1; if (tag >= 0) newES.Set(edge, (*oldES)[tag]); else newES.Clear(edge); } if (theHold.Holding()) theHold.Put(new ChangeNamedSetRestore(&patchData->eselSet, set, oldES)); patchData->eselSet[set] = newES; } // Now the patch selections for (set = 0; set < patchData->pselSet.Count(); ++set) { BitArray *oldPS = &patchData->pselSet[set]; BitArray newPS; newPS.SetSize(patch->numPatches); for (int p = 0; p < patch->numPatches; ++p) { // Get the knot's previous location, then copy that selection into the new set int tag = patch->patches[p].aux1; if (tag >= 0) newPS.Set(p, (*oldPS)[tag]); else newPS.Clear(p); } if (theHold.Holding()) theHold.Put(new ChangeNamedSetRestore(&patchData->pselSet, set, oldPS)); patchData->pselSet[set] = newPS; } // watje 4-16-99 patch->HookFixTopology(); patchData->SetFlag(EPD_BEENDONE, TRUE); } nodes.DisposeTemporary(); ClearPatchDataFlag(mcList, EPD_BEENDONE); }
void EditPatchMod::ActivateSubobjSel(int level, XFormModes& modes) { ModContextList mcList; INodeTab nodes; int old = selLevel; if (!ip) return; ip->GetModContexts(mcList, nodes); selLevel = level; // 3-10-99 watje if (level != EP_PATCH) { if (ip->GetCommandMode() == bevelMode) ip->SetStdCommandMode(CID_OBJMOVE); if (ip->GetCommandMode() == extrudeMode) ip->SetStdCommandMode(CID_OBJMOVE); if (inBevel) { ISpinnerControl *spin; spin = GetISpinner(GetDlgItem(hOpsPanel, IDC_EP_OUTLINESPINNER)); if (spin) { HWND hWnd = spin->GetHwnd(); SendMessage(hWnd, WM_LBUTTONUP, 0, 0); ReleaseISpinner(spin); } } if (inExtrude) { ISpinnerControl *spin; spin = GetISpinner(GetDlgItem(hOpsPanel, IDC_EP_EXTRUDESPINNER)); if (spin) { HWND hWnd = spin->GetHwnd(); SendMessage(hWnd, WM_LBUTTONUP, 0, 0); ReleaseISpinner(spin); } } } if (level != EP_VERTEX) { if (ip->GetCommandMode() == bindMode) ip->SetStdCommandMode(CID_OBJMOVE); } switch (level) { case EP_OBJECT: // Not imp. break; case EP_PATCH: modes = XFormModes(moveMode, rotMode, nuscaleMode, uscaleMode, squashMode, selectMode); break; case EP_EDGE: modes = XFormModes(moveMode, rotMode, nuscaleMode, uscaleMode, squashMode, selectMode); break; case EP_VERTEX: modes = XFormModes(moveMode, rotMode, nuscaleMode, uscaleMode, squashMode, selectMode); break; case EP_TILE: modes = XFormModes(NULL, NULL, NULL, NULL, NULL, selectMode); break; } if (selLevel != old) { SetSubobjectLevel(level); // Modify the caches to reflect the new sel level. for (int i = 0; i < mcList.Count(); i++) { EditPatchData *patchData =(EditPatchData*)mcList[i]->localData; if (!patchData) continue; if (patchData->tempData && patchData->TempData(this)->PatchCached(ip->GetTime())) { RPatchMesh *rpatch; PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch); if (patch) { if (selLevel == EP_VERTEX) patch->dispFlags = DISP_VERTS; else patch->dispFlags = 0; if (displayLattice) patch->SetDispFlag(DISP_LATTICE); patch->SetDispFlag(patchLevelDispFlags[selLevel]); patch->selLevel = patchLevel[selLevel]; rpatch->SetSelLevel (selLevel); } } } NotifyDependents(FOREVER, PART_SUBSEL_TYPE | PART_DISPLAY, REFMSG_CHANGE); ip->PipeSelLevelChanged(); // Update selection UI display, named sel SelectionChanged(); } nodes.DisposeTemporary(); }
void EditPatchMod::InvertSelection(int selLevel) { // Don't do anything if at vertex level with verts turned off if (selLevel == EP_VERTEX && !filterVerts) return; if (selLevel == EP_OBJECT) return; ModContextList mcList; INodeTab nodes; if (!ip) return; ip->GetModContexts(mcList, nodes); ip->ClearCurNamedSelSet(); for (int i = 0; i < mcList.Count(); i++) { EditPatchData *patchData =(EditPatchData*)mcList[i]->localData; if (!patchData) continue; RPatchMesh *rpatch; PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch); if (!patch) continue; patchData->BeginEdit(ip->GetTime()); if (theHold.Holding()) theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "InvertSelection")); switch (selLevel) { case EP_VERTEX: { patch->vertSel = ~patch->vertSel; break; } case EP_EDGE: { patch->edgeSel = ~patch->edgeSel; break; } case EP_PATCH: { patch->patchSel = ~patch->patchSel; break; } case EP_TILE: { rpatch->tileSel = ~rpatch->tileSel; break; } } UnselectHiddenPatches(selLevel, patch); patchData->UpdateChanges(patch, rpatch, FALSE); if (patchData->tempData) { patchData->TempData(this)->Invalidate(PART_SELECT); } PatchSelChanged(); } nodes.DisposeTemporary(); NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE); }
void EditPatchMod::NewSetFromCurSel(TSTR &setName) { MaybeFixupNamedSels(); ModContextList mcList; INodeTab nodes; if (!ip) return; ip->GetModContexts(mcList, nodes); for (int i = 0; i < mcList.Count(); i++) { EditPatchData *patchData =(EditPatchData*)mcList[i]->localData; if (!patchData) continue; RPatchMesh *rpatch; PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch); if (!patch) continue; GenericNamedSelSetList &sel = patchData->GetSelSet(this); BitArray *exist = sel.GetSet(setName); switch (selLevel) { case EP_VERTEX: if (exist) { *exist = patch->vertSel; } else { patchData->vselSet.AppendSet(patch->vertSel, 0, setName); } break; case EP_PATCH: if (exist) { *exist = patch->patchSel; } else { patchData->pselSet.AppendSet(patch->patchSel, 0, setName); } break; case EP_EDGE: if (exist) { *exist = patch->edgeSel; } else { patchData->eselSet.AppendSet(patch->edgeSel, 0, setName); } break; } } int index = FindSet(setName, selLevel); if (index < 0) AddSet(setName, selLevel); nodes.DisposeTemporary(); }
int EditPatchMod::DoAttach(INode *node, PatchMesh *attPatch, RPatchMesh *rattPatch, bool & canUndo) { ModContextList mcList; INodeTab nodes; if (!ip) return 0; ip->GetModContexts(mcList, nodes); if (mcList.Count() != 1) { nodes.DisposeTemporary(); return 0; } EditPatchData *patchData =(EditPatchData*)mcList[0]->localData; if (!patchData) { nodes.DisposeTemporary(); return 0; } patchData->BeginEdit(ip->GetTime()); // If the mesh isn't yet cached, this will cause it to get cached. RPatchMesh *rpatch; PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch); if (!patch) { nodes.DisposeTemporary(); return 0; } patchData->RecordTopologyTags(patch); RecordTopologyTags(); // Transform the shape for attachment: // If reorienting, just translate to align pivots // Otherwise, transform to match our transform Matrix3 attMat(1); if (attachReorient) { Matrix3 thisTM = nodes[0]->GetNodeTM(ip->GetTime()); Matrix3 thisOTMBWSM = nodes[0]->GetObjTMBeforeWSM(ip->GetTime()); Matrix3 thisPivTM = thisTM * Inverse(thisOTMBWSM); Matrix3 otherTM = node->GetNodeTM(ip->GetTime()); Matrix3 otherOTMBWSM = node->GetObjTMBeforeWSM(ip->GetTime()); Matrix3 otherPivTM = otherTM * Inverse(otherOTMBWSM); Point3 otherObjOffset = node->GetObjOffsetPos(); attMat = Inverse(otherPivTM) * thisPivTM; } else { attMat = node->GetObjectTM(ip->GetTime()) * Inverse(nodes[0]->GetObjectTM(ip->GetTime())); } // RB 3-17-96 : Check for mirroring AffineParts parts; decomp_affine(attMat, &parts); if (parts.f < 0.0f) { int v[8], ct, ct2, j; Point3 p[9]; for (int i = 0; i < attPatch->numPatches; i++) { // Re-order rpatch if (attPatch->patches[i].type == PATCH_QUAD) { UI_PATCH rpatch=rattPatch->getUIPatch (i); int ctU=rpatch.NbTilesU<<1; int ctV=rpatch.NbTilesV<<1; int nU; for (nU=0; nU<ctU; nU++) { for (int nV=0; nV<ctV; nV++) { rattPatch->getUIPatch (i).getTileDesc (nU+nV*ctU)=rpatch.getTileDesc (ctU-1-nU+(ctV-1-nV)*ctU); } } for (nU=0; nU<ctU+1; nU++) { for (int nV=0; nV<ctV+1; nV++) { rattPatch->getUIPatch (i).setColor (nU+nV*(ctU+1), rpatch.getColor (ctU-nU+(ctV-nV)*ctU)); } } } // Re-order vertices ct = attPatch->patches[i].type == PATCH_QUAD ? 4 : 3; for (j = 0; j < ct; j++) { v[j] = attPatch->patches[i].v[j]; } for (j = 0; j < ct; j++) { attPatch->patches[i].v[j] = v[ct - j - 1]; } // Re-order vecs ct = attPatch->patches[i].type == PATCH_QUAD ? 8 : 6; ct2 = attPatch->patches[i].type == PATCH_QUAD ? 5 : 3; for (j = 0; j < ct; j++) { v[j] = attPatch->patches[i].vec[j]; } for (j = 0; j < ct; j++, ct2--) { if (ct2 < 0) ct2 = ct - 1; attPatch->patches[i].vec[j] = v[ct2]; } // Re-order enteriors if (attPatch->patches[i].type == PATCH_QUAD) { ct = 4; for (j = 0; j < ct; j++) { v[j] = attPatch->patches[i].interior[j]; } for (j = 0; j < ct; j++) { attPatch->patches[i].interior[j] = v[ct - j - 1]; } } // Re-order aux if (attPatch->patches[i].type == PATCH_TRI) { ct = 9; for (j = 0; j < ct; j++) { p[j] = attPatch->patches[i].aux[j]; } for (j = 0; j < ct; j++) { attPatch->patches[i].aux[j] = p[ct - j - 1]; } } // Re-order TV faces if present for (int chan = 0; chan < patch->getNumMaps(); ++chan) { if (attPatch->tvPatches[chan]) { ct = 4; for (j = 0; j < ct; j++) { v[j] = attPatch->tvPatches[chan][i].tv[j]; } for (j = 0; j < ct; j++) { attPatch->tvPatches[chan][i].tv[j] = v[ct - j - 1]; } } } } } int i; for (i = 0; i < attPatch->numVerts; ++i) attPatch->verts[i].p = attPatch->verts[i].p * attMat; for (i = 0; i < attPatch->numVecs; ++i) attPatch->vecs[i].p = attPatch->vecs[i].p * attMat; attPatch->computeInteriors(); theHold.Begin(); // Combine the materials of the two nodes. int mat2Offset = 0; Mtl *m1 = nodes[0]->GetMtl(); Mtl *m2 = node->GetMtl(); bool condenseMe = FALSE; if (m1 && m2 &&(m1 != m2)) { if (attachMat == ATTACHMAT_IDTOMAT) { int ct = 1; if (m1->IsMultiMtl()) ct = m1->NumSubMtls(); for (int i = 0; i < patch->numPatches; ++i) { int mtid = patch->getPatchMtlIndex(i); if (mtid >= ct) patch->setPatchMtlIndex(i, mtid % ct); } FitPatchIDsToMaterial(*attPatch, m2); if (condenseMat) condenseMe = TRUE; } // the theHold calls here were a vain attempt to make this all undoable. // This should be revisited in the future so we don't have to use the SYSSET_CLEAR_UNDO. theHold.Suspend(); if (attachMat == ATTACHMAT_MATTOID) { m1 = FitMaterialToPatchIDs(*patch, m1); m2 = FitMaterialToPatchIDs(*attPatch, m2); } Mtl *multi = CombineMaterials(m1, m2, mat2Offset); if (attachMat == ATTACHMAT_NEITHER) mat2Offset = 0; theHold.Resume(); // We can't be in face subobject mode, else we screw up the materials: DWORD oldSL = patch->selLevel; DWORD roldSL = patch->selLevel; patch->selLevel = PATCH_OBJECT; rpatch->SetSelLevel (EP_OBJECT); nodes[0]->SetMtl(multi); patch->selLevel = oldSL; rpatch->SetSelLevel (roldSL); m1 = multi; canUndo = FALSE; // Absolutely cannot undo material combinations. } if (!m1 && m2) { // We can't be in face subobject mode, else we screw up the materials: DWORD oldSL = patch->selLevel; DWORD roldSL = rpatch->GetSelLevel(); patch->selLevel = PATCH_OBJECT; rpatch->SetSelLevel (EP_OBJECT); nodes[0]->SetMtl(m2); patch->selLevel = oldSL; rpatch->SetSelLevel (roldSL); m1 = m2; } // Start a restore object... if (theHold.Holding()) theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "DoAttach")); // Do the attach patch->Attach(attPatch, mat2Offset); rpatch->Attach(rattPatch, *patch); patchData->UpdateChanges(patch, rpatch); patchData->TempData(this)->Invalidate(PART_TOPO | PART_GEOM); // Get rid of the original node ip->DeleteNode(node); ResolveTopoChanges(); theHold.Accept(GetString(IDS_TH_ATTACH)); if (m1 && condenseMe) { // Following clears undo stack. patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch); m1 = CondenseMatAssignments(*patch, m1); } nodes.DisposeTemporary(); ClearPatchDataFlag(mcList, EPD_BEENDONE); NotifyDependents(FOREVER, PART_TOPO | PART_GEOM, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL); return 1; }
void EditPatchMod::DoAddHook(PatchMesh *pMesh, int vert0, int vert1, int vert2, int seg, int config) { ModContextList mcList; INodeTab nodes; TimeValue t = ip->GetTime(); BOOL holdNeeded = FALSE; BOOL hadSelected = FALSE; if (!ip) return; ip->GetModContexts(mcList, nodes); if (mcList.Count() != 1) return; ClearPatchDataFlag(mcList, EPD_BEENDONE); theHold.Begin(); // RecordTopologyTags(); for (int i = 0; i < mcList.Count(); i++) { BOOL altered = FALSE; 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) ||(patch != pMesh)) 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->vertSel.NumberSet()) { altered = holdNeeded = TRUE; if (theHold.Holding()) theHold.Put(new PatchRestore(patchData, this, patch, rpatch)); // Call the vertex type change function // ** Hulud bug hack for hooking my way \\\\\\\\\/////////// //patch->AddHook(vert1, seg); // Config 0 switch (config) { case 0: rpatch->AddHook (vert1, seg, *patch); break; case 1: rpatch->AddHook (vert0, vert1, vert2, seg, *patch); break; default: nlassert (0); } // ** //////////\\\\\\\\\\ // patch->UpdateHooks(); // InvalidateMesh(); patchData->UpdateChanges(patch, rpatch); patchData->TempData(this)->Invalidate(PART_TOPO); // } patchData->SetFlag(EPD_BEENDONE, TRUE); } if (holdNeeded) { // ResolveTopoChanges(); theHold.Accept(GetString(IDS_TH_PATCHCHANGE)); } else { ip->DisplayTempPrompt(GetString(IDS_TH_NOPATCHESSEL), PROMPT_TIME); theHold.End(); } nodes.DisposeTemporary(); ClearPatchDataFlag(mcList, EPD_BEENDONE); NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL); /* // If any bits are set in the selection set, let's DO IT!! if (!ip) return; theHold.Begin(); POPatchGenRecord *rec = new POPatchGenRecord(this); if (theHold.Holding()) theHold.Put(new PatchObjectRestore(this, rec)); // Call the patch type change function patch.AddHook(); patch.InvalidateGeomCache(); InvalidateMesh(); theHold.Accept(GetResString(IDS_TH_PATCHCHANGE)); NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL); */ }
void EditPatchMod::DoRemoveHook() { ModContextList mcList; INodeTab nodes; TimeValue t = ip->GetTime(); BOOL holdNeeded = FALSE; BOOL hadSelected = FALSE; if (!ip) return; ip->GetModContexts(mcList, nodes); ClearPatchDataFlag(mcList, EPD_BEENDONE); theHold.Begin(); RecordTopologyTags(); for (int i = 0; i < mcList.Count(); i++) { BOOL altered = FALSE; 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->vertSel.NumberSet()) { altered = holdNeeded = TRUE; if (theHold.Holding()) theHold.Put(new PatchRestore(patchData, this, patch, rpatch)); // Call the vertex type change function // Modif by Hulud //patch->RemoveHook(); rpatch->RemoveHook (*patch); // patch->InvalidateGeomCache(); // InvalidateMesh(); patchData->UpdateChanges(patch, rpatch); patchData->TempData(this)->Invalidate(PART_TOPO); } patchData->SetFlag(EPD_BEENDONE, TRUE); } if (holdNeeded) { ResolveTopoChanges(); theHold.Accept(GetString(IDS_TH_PATCHCHANGE)); } else { ip->DisplayTempPrompt(GetString(IDS_TH_NOPATCHESSEL), PROMPT_TIME); theHold.End(); } nodes.DisposeTemporary(); ClearPatchDataFlag(mcList, EPD_BEENDONE); NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL); }
// 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); }
void EditPatchMod::UpdateSelectDisplay() { TSTR buf; int num, j; if (!hSelectPanel) return; ModContextList mcList; INodeTab nodes; if (!ip) return; ip->GetModContexts(mcList, nodes); switch (GetSubobjectLevel()) { case EP_OBJECT: buf.printf(GetString(IDS_TH_OBJECT_SEL)); break; case EP_VERTEX: { num = 0; PatchMesh *thePatch = NULL; for (int i = 0; i < mcList.Count(); i++) { EditPatchData *patchData =(EditPatchData*)mcList[i]->localData; if (!patchData) continue; if (patchData->tempData && patchData->TempData(this)->PatchCached(ip->GetTime())) { RPatchMesh *rpatch; PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch); if (!patch) continue; int thisNum = patch->vertSel.NumberSet(); if (thisNum) { num += thisNum; thePatch = patch; } } } if (num == 1) { for (j = 0; j < thePatch->vertSel.GetSize(); j++) if (thePatch->vertSel[j]) break; buf.printf(GetString(IDS_TH_NUMVERTSEL), j + 1); } else buf.printf(GetString(IDS_TH_NUMVERTSELP), num); } break; case EP_PATCH: { num = 0; PatchMesh *thePatch = NULL; for (int i = 0; i < mcList.Count(); i++) { EditPatchData *patchData =(EditPatchData*)mcList[i]->localData; if (!patchData) continue; if (patchData->tempData && patchData->TempData(this)->PatchCached(ip->GetTime())) { RPatchMesh *rpatch; PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch); if (!patch) continue; int thisNum = patch->patchSel.NumberSet(); if (thisNum) { num += thisNum; thePatch = patch; } } } if (num == 1) { for (j = 0; j < thePatch->patchSel.GetSize(); j++) if (thePatch->patchSel[j]) break; buf.printf(GetString(IDS_TH_NUMPATCHSEL), j + 1); } else buf.printf(GetString(IDS_TH_NUMPATCHSELP), num); } break; case EP_EDGE: { num = 0; PatchMesh *thePatch = NULL; for (int i = 0; i < mcList.Count(); i++) { EditPatchData *patchData =(EditPatchData*)mcList[i]->localData; if (!patchData) continue; if (patchData->tempData && patchData->TempData(this)->PatchCached(ip->GetTime())) { RPatchMesh *rpatch; PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch); if (!patch) continue; int thisNum = patch->edgeSel.NumberSet(); if (thisNum) { num += thisNum; thePatch = patch; } } } if (num == 1) { for (j = 0; j < thePatch->edgeSel.GetSize(); j++) if (thePatch->edgeSel[j]) break; buf.printf(GetString(IDS_TH_NUMEDGESEL), j + 1); } else buf.printf(GetString(IDS_TH_NUMEDGESELP), num); } break; case EP_TILE: { num = 0; RPatchMesh *thePatch = NULL; for (int i = 0; i < mcList.Count(); i++) { EditPatchData *patchData =(EditPatchData*)mcList[i]->localData; if (!patchData) continue; if (patchData->tempData && patchData->TempData(this)->PatchCached(ip->GetTime())) { RPatchMesh *rpatch; PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch); if (!patch) continue; int thisNum = rpatch->tileSel.NumberSet(); if (thisNum) { num += thisNum; thePatch = rpatch; } } } if (num == 1) { for (j = 0; j < thePatch->tileSel.GetSize(); j++) if (thePatch->tileSel[j]) break; buf.printf("Tile %d Selected", j + 1); } else buf.printf("%d Tiles Selected", num); } break; } nodes.DisposeTemporary(); SetDlgItemText(hSelectPanel, IDC_NUMSEL_LABEL, buf); }
void EditPatchMod::SelectionChanged() { if (hSelectPanel) { UpdateSelectDisplay(); InvalidateRect(hSelectPanel, NULL, FALSE); } // Now see if the selection set matches one of the named selections! if (ip &&(selLevel != EP_OBJECT)&&(selLevel != EP_TILE)) { ModContextList mcList; INodeTab nodes; TimeValue t = ip->GetTime(); ip->GetModContexts(mcList, nodes); int sublevel = selLevel - 1; int dataSet; for (int set = 0; set < namedSel[sublevel].Count(); ++set) { ClearPatchDataFlag(mcList, EPD_BEENDONE); BOOL gotMatch = FALSE; for (int i = 0; i < mcList.Count(); i++) { EditPatchData *patchData =(EditPatchData*)mcList[i]->localData; if (!patchData) continue; if (patchData->GetFlag(EPD_BEENDONE)) continue; RPatchMesh *rpatch; PatchMesh *patch = patchData->TempData(this)->GetPatch(t, rpatch); if (!patch) continue; // See if this patch has the named selection set switch (selLevel) { case EP_VERTEX: for (dataSet = 0; dataSet < patchData->vselSet.Count(); ++dataSet) { if (*(patchData->vselSet.names[dataSet]) == *namedSel[sublevel][set]) { if (!(*patchData->vselSet.sets[set] == patch->vertSel)) goto next_set; gotMatch = TRUE; break; } } break; case EP_EDGE: for (dataSet = 0; dataSet < patchData->eselSet.Count(); ++dataSet) { if (*(patchData->eselSet.names[dataSet]) == *namedSel[sublevel][set]) { if (!(*patchData->eselSet.sets[set] == patch->edgeSel)) goto next_set; gotMatch = TRUE; break; } } break; case EP_PATCH: for (dataSet = 0; dataSet < patchData->pselSet.Count(); ++dataSet) { if (*(patchData->pselSet.names[dataSet]) == *namedSel[sublevel][set]) { if (!(*patchData->pselSet.sets[set] == patch->patchSel)) goto next_set; gotMatch = TRUE; break; } } break; } patchData->SetFlag(EPD_BEENDONE, TRUE); } // If we reach here, we might have a set that matches if (gotMatch) { ip->SetCurNamedSelSet(*namedSel[sublevel][set]); goto namedSelUpdated; } next_set:; } // No set matches, clear the named selection ip->ClearCurNamedSelSet(); namedSelUpdated: nodes.DisposeTemporary(); ClearPatchDataFlag(mcList, EPD_BEENDONE); } }
void EditPatchMod::DoVertReset () { ModContextList mcList; INodeTab nodes; TimeValue t = ip->GetTime(); int holdNeeded = 0; BOOL hadSel = FALSE; if (!ip) return; ip->GetModContexts(mcList, nodes); ClearPatchDataFlag(mcList, EPD_BEENDONE); theHold.Begin(); RecordTopologyTags(); for (int i = 0; i < mcList.Count(); i++) { BOOL altered = FALSE; 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->vertSel.NumberSet() > 0) { hadSel = TRUE; if (theHold.Holding()) theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "DoVertReset")); // Call the patch weld function ResetVert (patch); patchData->UpdateChanges(patch, rpatch); patchData->TempData(this)->Invalidate(PART_GEOM); /*if (patch->Weld(weldThreshold)) { rpatch->Weld (patch); altered = holdNeeded = TRUE; patchData->UpdateChanges(patch, rpatch); patchData->TempData(this)->Invalidate(PART_TOPO); }*/ } patchData->SetFlag(EPD_BEENDONE, TRUE); } ResolveTopoChanges(); theHold.Accept("Reset Vertex"); /*if (holdNeeded) { ResolveTopoChanges(); theHold.Accept(GetString(IDS_TH_VERTWELD)); } else { if (!hadSel) ip->DisplayTempPrompt(GetString(IDS_TH_NOVERTSSEL), PROMPT_TIME); else ip->DisplayTempPrompt(GetString(IDS_TH_NOWELDPERFORMED), PROMPT_TIME); theHold.End(); }*/ nodes.DisposeTemporary(); ClearPatchDataFlag(mcList, EPD_BEENDONE); NotifyDependents(FOREVER, PART_GEOM, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL); }
void MaterialUIHandler::UpdateCurrentMaterial (HWND hWnd, EPolyMod *pMod, TimeValue t, Interval & validity) { MtlID mat = 0; bool determined = false; if (pMod->GetPolyOperationID() == ep_op_set_material) { int materialHolder; pMod->getParamBlock()->GetValue (epm_material, t, materialHolder, validity); mat = materialHolder; determined = true; } else { bool useStackSelection = pMod->getParamBlock()->GetInt (epm_stack_selection) != 0; bool init = false; ModContextList list; INodeTab nodes; pMod->EpModGetIP()->GetModContexts (list, nodes); int i; for (i=0; i<list.Count(); i++) { EditPolyData *pData = (EditPolyData *) list[i]->localData; if (!pData) continue; MNMesh *pMesh = pData->GetMesh(); if (!pMesh) { validity = NEVER; continue; } DWORD l_selFlag = useStackSelection ? MN_EDITPOLY_STACK_SELECT:MN_SEL; int j; for (j=0; j<pMesh->numf; j++) { if (!pMesh->f[j].GetFlag (l_selFlag)) continue; if (pMesh->f[j].GetFlag (MN_DEAD)) continue; if (!init) { mat = pMesh->f[j].material; init = true; } else if (mat != pMesh->f[j].material) break; } if (j<pMesh->numf) break; } nodes.DisposeTemporary (); determined = (i>=list.Count()) && init; } ISpinnerControl *spin = GetISpinner(GetDlgItem(hWnd,IDC_MAT_IDSPIN)); spin->SetIndeterminate(!determined); if (determined) spin->SetValue (int(mat+1), FALSE); ReleaseISpinner(spin); spin = GetISpinner(GetDlgItem(hWnd,IDC_MAT_IDSPIN_SEL)); spin->SetIndeterminate(!determined); if (determined) spin->SetValue (int(mat+1), FALSE); ReleaseISpinner(spin); if (GetDlgItem (hWnd, IDC_MTLID_NAMES_COMBO)) { ValidateUINameCombo(hWnd, pMod); } }