#include "stdafx.h" #include "editpat.h" // ------------------------------------------------------------------------------------------------------------------------------------------------------ #define DBGWELD_DUMPx #define DBGWELD_ACTIONx #define DBG_NAMEDSELSx #define PROMPT_TIME 2000 // ------------------------------------------------------------------------------------------------------------------------------------------------------ extern void ChangePatchType(PatchMesh *patch, int index, int type); // ------------------------------------------------------------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------------------------------------------------------------ int EditPatchMod::RememberPatchThere(HWND hWnd, IPoint2 m) { ModContextList mcList; INodeTab nodes; TimeValue t = ip->GetTime(); // Initialize so there isn't any remembered patch rememberedPatch = NULL; if (!ip) return 0; ip->GetModContexts(mcList, nodes); ClearPatchDataFlag(mcList, EPD_BEENDONE); // See if we're over a patch ViewExp *vpt = ip->GetViewport(hWnd); GraphicsWindow *gw = vpt->getGW(); HitRegion hr; MakeHitRegion(hr, HITTYPE_POINT, 1, 4, &m); gw->setHitRegion(&hr); SubPatchHitList hitList; int result = 0; 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; INode *inode = nodes[i]; Matrix3 mat = inode->GetObjectTM(t); gw->setTransform(mat); patch->SubObjectHitTest(gw, gw->getMaterial(), &hr, SUBHIT_PATCH_PATCHES/* | HIT_ABORTONHIT*/, hitList); PatchSubHitRec *hit = hitList.First(); if (hit) { result = 1; // Go thru the list and see if we have one that's selected // If more than one selected and they're different types, set unknown type hit = hitList.First(); while (hit) { if (patch->patchSel[hit->index]) { if (patch->SelPatchesSameType()) { rememberedPatch = NULL; rememberedData = patch->patches[hit->index].flags &(~PATCH_INTERIOR_MASK); goto finish; } // Selected patches not all the same type! rememberedPatch = NULL; rememberedData = -1; // Not all the same! goto finish; } hit = hit->Next(); } if (ip->SelectionFrozen()) goto finish; // Select just this patch hit = hitList.First(); theHold.Begin(); if (theHold.Holding()) theHold.Put(new PatchSelRestore(patchData, this, patch)); patch->patchSel.ClearAll(); patch->patchSel.Set(hit->index); patchData->UpdateChanges(patch, rpatch, FALSE); theHold.Accept(GetString(IDS_DS_SELECT)); NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL); PatchSelChanged(); rememberedPatch = patch; rememberedIndex = hit->index; rememberedData = patch->patches[rememberedIndex].flags &(~PATCH_INTERIOR_MASK); } patchData->SetFlag(EPD_BEENDONE, TRUE); } finish: nodes.DisposeTemporary(); ClearPatchDataFlag(mcList, EPD_BEENDONE); if (vpt) ip->ReleaseViewport(vpt); return result; } // ------------------------------------------------------------------------------------------------------------------------------------------------------ void EditPatchMod::ChangeRememberedPatch(int type) { ModContextList mcList; INodeTab nodes; TimeValue t = ip->GetTime(); if (!ip) return; 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; if (patch == rememberedPatch) { // If this is the first edit, then the delta arrays will be allocated patchData->BeginEdit(t); theHold.Begin(); if (theHold.Holding()) theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "ChangeRememberedPatch")); // Call the patch type change function ChangePatchType(patch, rememberedIndex, type); patchData->UpdateChanges(patch, rpatch, FALSE); patchData->TempData(this)->Invalidate(PART_TOPO); theHold.Accept(GetString(IDS_TH_PATCHCHANGE)); ClearPatchDataFlag(mcList, EPD_BEENDONE); NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL); nodes.DisposeTemporary(); return; } patchData->SetFlag(EPD_BEENDONE, TRUE); } nodes.DisposeTemporary(); ClearPatchDataFlag(mcList, EPD_BEENDONE); } // ------------------------------------------------------------------------------------------------------------------------------------------------------ int EditPatchMod::RememberVertThere(HWND hWnd, IPoint2 m) { ModContextList mcList; INodeTab nodes; TimeValue t = ip->GetTime(); // Initialize so there isn't any remembered patch rememberedPatch = NULL; if (!ip) return 0; ip->GetModContexts(mcList, nodes); ClearPatchDataFlag(mcList, EPD_BEENDONE); // See if we're over a vertex ViewExp *vpt = ip->GetViewport(hWnd); GraphicsWindow *gw = vpt->getGW(); HitRegion hr; MakeHitRegion(hr, HITTYPE_POINT, 1, 4, &m); gw->setHitRegion(&hr); SubPatchHitList hitList; int result = 0; 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; INode *inode = nodes[i]; Matrix3 mat = inode->GetObjectTM(t); gw->setTransform(mat); patch->SubObjectHitTest(gw, gw->getMaterial(), &hr, SUBHIT_PATCH_VERTS/* | HIT_ABORTONHIT*/, hitList); PatchSubHitRec *hit = hitList.First(); if (hit) { result = 1; // Go thru the list and see if we have one that's selected // If more than one selected and they're different types, set unknown type hit = hitList.First(); while (hit) { if (patch->vertSel[hit->index]) { if (patch->SelVertsSameType()) { rememberedPatch = NULL; rememberedData = patch->verts[hit->index].flags &(~PVERT_TYPE_MASK); goto finish; } // Selected verts not all the same type! rememberedPatch = NULL; rememberedData = -1; // Not all the same! goto finish; } hit = hit->Next(); } if (ip->SelectionFrozen()) goto finish; // Select just this vertex hit = hitList.First(); theHold.Begin(); if (theHold.Holding()) theHold.Put(new PatchSelRestore(patchData, this, patch)); patch->vertSel.ClearAll(); patch->vertSel.Set(hit->index); patchData->UpdateChanges(patch, rpatch, FALSE); theHold.Accept(GetString(IDS_DS_SELECT)); NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL); PatchSelChanged(); rememberedPatch = patch; rememberedIndex = hit->index; rememberedData = patch->verts[rememberedIndex].flags &(~PVERT_TYPE_MASK); } patchData->SetFlag(EPD_BEENDONE, TRUE); } finish: nodes.DisposeTemporary(); ClearPatchDataFlag(mcList, EPD_BEENDONE); if (vpt) ip->ReleaseViewport(vpt); return result; } // ------------------------------------------------------------------------------------------------------------------------------------------------------ void EditPatchMod::ChangeRememberedVert(int type) { ModContextList mcList; INodeTab nodes; TimeValue t = ip->GetTime(); if (!ip) return; 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; if (patch == rememberedPatch) { // If this is the first edit, then the delta arrays will be allocated patchData->BeginEdit(t); theHold.Begin(); if (theHold.Holding()) theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "ChangeRememberedVert")); // Call the vertex type change function patch->ChangeVertType(rememberedIndex, type); patchData->UpdateChanges(patch, rpatch, FALSE); patchData->TempData(this)->Invalidate(PART_TOPO); theHold.Accept(GetString(IDS_TH_VERTCHANGE)); ClearPatchDataFlag(mcList, EPD_BEENDONE); NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE); ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL); nodes.DisposeTemporary(); return; } patchData->SetFlag(EPD_BEENDONE, TRUE); } nodes.DisposeTemporary(); ClearPatchDataFlag(mcList, EPD_BEENDONE); } // ------------------------------------------------------------------------------------------------------------------------------------------------------