Before Width: | Height: | Size: 326 B |
@ -1,21 +0,0 @@
|
||||
FILE(GLOB SRC *.cpp *.h *.def)
|
||||
|
||||
ADD_LIBRARY(nel_patch_edit_adv SHARED ${SRC} mods.rc)
|
||||
|
||||
INCLUDE_DIRECTORIES(${MAXSDK_INCLUDE_DIR})
|
||||
TARGET_LINK_LIBRARIES(nel_patch_edit_adv
|
||||
nelmisc
|
||||
nel3d
|
||||
nel_mesh_lib
|
||||
nel_patch_lib
|
||||
nel_3dsmax_shared
|
||||
${MAXSDK_LIBRARIES}
|
||||
Version.lib
|
||||
comctl32.lib)
|
||||
|
||||
SET_TARGET_PROPERTIES(nel_patch_edit_adv PROPERTIES SUFFIX ".dlm")
|
||||
NL_DEFAULT_PROPS(nel_patch_edit_adv "MAX Plugin: NeL Patch Edit (Adv)")
|
||||
NL_ADD_RUNTIME_FLAGS(nel_patch_edit_adv)
|
||||
NL_ADD_LIB_SUFFIX(nel_patch_edit_adv)
|
||||
|
||||
INSTALL(TARGETS nel_patch_edit_adv RUNTIME DESTINATION maxplugin/plugins LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries)
|
Before Width: | Height: | Size: 326 B |
@ -1,857 +0,0 @@
|
||||
|
||||
/**********************************************************************
|
||||
*<
|
||||
FILE: editpat.cpp
|
||||
|
||||
DESCRIPTION: Edit Patch OSM
|
||||
|
||||
CREATED BY: Tom Hudson, Dan Silva & Rolf Berteig
|
||||
|
||||
HISTORY: created 23 June, 1995
|
||||
|
||||
IMPORTANT USAGE NOTE:
|
||||
|
||||
When you do an operation in edit patch which will change the topology, the form
|
||||
of the code should look like this code, taken from the vertex deletion:
|
||||
|
||||
-----
|
||||
|
||||
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.
|
||||
PatchMesh *patch = patchData->TempData(this)->GetPatch(t);
|
||||
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 = 1;
|
||||
if (theHold.Holding())
|
||||
theHold.Put(new PatchRestore(patchData, this, patch, "DoVertDelete"));
|
||||
// Call the vertex delete function
|
||||
DeleteSelVerts(patch);
|
||||
--> patchData->UpdateChanges(patch);
|
||||
patchData->TempData(this)->Invalidate(PART_TOPO);
|
||||
}
|
||||
patchData->SetFlag(EPD_BEENDONE, TRUE);
|
||||
}
|
||||
|
||||
if (holdNeeded)
|
||||
{
|
||||
--> ResolveTopoChanges();
|
||||
theHold.Accept(GetString(IDS_TH_VERTDELETE));
|
||||
}
|
||||
else
|
||||
{
|
||||
ip->DisplayTempPrompt(GetString(IDS_TH_NOVERTSSEL), PROMPT_TIME);
|
||||
theHold.End();
|
||||
}
|
||||
|
||||
nodes.DisposeTemporary();
|
||||
ClearPatchDataFlag(mcList, EPD_BEENDONE);
|
||||
|
||||
-----
|
||||
|
||||
The key elements in the "changed topology" case are the calls noted by arrows.
|
||||
These record special tags inside the object so that after the topology is changed
|
||||
by the modifier code, the UpdateChanges code can make a new mapping from the old
|
||||
object topology to the new.
|
||||
|
||||
If the operation doesn't change the topology, then the three topology tag calls
|
||||
aren't needed and the UpdateChanges call becomes:
|
||||
|
||||
patchData->UpdateChanges(patch, FALSE);
|
||||
|
||||
This tells UpdateChanges not to bother remapping the topology.
|
||||
|
||||
*> Copyright(c) 1994, All Rights Reserved.
|
||||
**********************************************************************/
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
#include "../nel_patch_lib/vertex_neighborhood.h"
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
// Uncomment this for vert mapper debugging
|
||||
//#define VMAP_DEBUG 1
|
||||
|
||||
// Forward references
|
||||
BOOL CALLBACK PatchSelectDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
BOOL CALLBACK PatchOpsDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
BOOL CALLBACK PatchObjSurfDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
BOOL CALLBACK PatchSurfDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
BOOL CALLBACK PatchTileDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
BOOL CALLBACK PatchEdgeDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
void ResetVert (PatchMesh *patch);
|
||||
|
||||
// A handy zero point
|
||||
Point3 zeroPoint(0, 0, 0);
|
||||
|
||||
// Our temporary prompts last 2 seconds:
|
||||
#define PROMPT_TIME 2000
|
||||
|
||||
// in mods.cpp
|
||||
extern HINSTANCE hInstance;
|
||||
|
||||
// Select by material parameters
|
||||
int sbmParams[4] = {1, 1, RPO_DEFAULT_TESSEL, RPO_DEFAULT_TESSEL};
|
||||
|
||||
// Select by smooth parameters
|
||||
DWORD sbsParams[3] = {1, 1, 0};
|
||||
|
||||
float weldThreshold = 0.1f;
|
||||
|
||||
// Checkbox items for rollup pages
|
||||
|
||||
int attachReorient = 0;
|
||||
// This is a special override value which allows us to hit-test on
|
||||
// any sub-part of a patch
|
||||
|
||||
extern int patchHitOverride; // If zero, no override is done
|
||||
|
||||
void SetPatchHitOverride(int value)
|
||||
{
|
||||
patchHitOverride = value;
|
||||
}
|
||||
|
||||
void ClearPatchHitOverride()
|
||||
{
|
||||
patchHitOverride = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PatchDeleteUser pDel;
|
||||
extern PatchRightMenu pMenu;
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
|
||||
static EditPatchClassDesc editPatchDesc;
|
||||
extern ClassDesc* GetEditPatchModDesc() { return &editPatchDesc; }
|
||||
|
||||
void EditPatchClassDesc::ResetClassParams(BOOL fileReset)
|
||||
{
|
||||
sbmParams[0] = 1;
|
||||
sbmParams[1] = 1;
|
||||
sbmParams[2] = RPO_DEFAULT_TESSEL;
|
||||
sbmParams[3] = RPO_DEFAULT_TESSEL;
|
||||
EditPatchMod::condenseMat = FALSE;
|
||||
EditPatchMod::attachMat = ATTACHMAT_IDTOMAT;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
|
||||
int EditPatchMod::Display(TimeValue t, INode* inode, ViewExp *vpt, int flags, ModContext *mc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EditPatchMod::GetWorldBoundBox(TimeValue t, INode* inode, ViewExp *vpt, Box3& box, ModContext *mc)
|
||||
{
|
||||
box.Init();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// UI stuff
|
||||
|
||||
void EditPatchMod::RecordTopologyTags()
|
||||
{
|
||||
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;
|
||||
patch->RecordTopologyTags();
|
||||
patchData->SetFlag(EPD_BEENDONE, TRUE);
|
||||
}
|
||||
|
||||
nodes.DisposeTemporary();
|
||||
ClearPatchDataFlag(mcList, EPD_BEENDONE);
|
||||
}
|
||||
|
||||
class ChangeNamedSetRestore : public RestoreObj
|
||||
{
|
||||
public:
|
||||
BitArray oldset, newset;
|
||||
int index;
|
||||
GenericNamedSelSetList *setList;
|
||||
|
||||
ChangeNamedSetRestore(GenericNamedSelSetList *sl, int ix, BitArray *o)
|
||||
{
|
||||
setList = sl;
|
||||
index = ix;
|
||||
oldset = *o;
|
||||
}
|
||||
void Restore(int isUndo)
|
||||
{
|
||||
newset = *(setList->sets[index]);
|
||||
*(setList->sets[index]) = oldset;
|
||||
}
|
||||
void Redo()
|
||||
{
|
||||
*(setList->sets[index]) = newset;
|
||||
}
|
||||
|
||||
TSTR Description() {return TSTR(_T("Change Named Sel Set"));}
|
||||
};
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
class EPModContextEnumProc : public ModContextEnumProc
|
||||
{
|
||||
float f;
|
||||
public:
|
||||
EPModContextEnumProc(float f) { this->f = f; }
|
||||
BOOL proc(ModContext *mc); // Return FALSE to stop, TRUE to continue.
|
||||
};
|
||||
|
||||
BOOL EPModContextEnumProc::proc(ModContext *mc)
|
||||
{
|
||||
EditPatchData *patchData =(EditPatchData*)mc->localData;
|
||||
if (patchData)
|
||||
patchData->RescaleWorldUnits(f);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// World scaling
|
||||
void EditPatchMod::RescaleWorldUnits(float f)
|
||||
{
|
||||
if (TestAFlag(A_WORK1))
|
||||
return;
|
||||
SetAFlag(A_WORK1);
|
||||
|
||||
// rescale all our references
|
||||
for (int i = 0; i < NumRefs(); i++)
|
||||
{
|
||||
ReferenceMaker *srm = GetReference(i);
|
||||
if (srm)
|
||||
srm->RescaleWorldUnits(f);
|
||||
}
|
||||
|
||||
// Now rescale stuff inside our data structures
|
||||
EPModContextEnumProc proc(f);
|
||||
EnumModContexts(&proc);
|
||||
NotifyDependents(FOREVER, PART_GEOM, REFMSG_CHANGE);
|
||||
}
|
||||
|
||||
void EditPatchMod::InvalidateSurfaceUI()
|
||||
{
|
||||
if (hSurfPanel && selLevel == EP_PATCH)
|
||||
{
|
||||
InvalidateRect(hSurfPanel, NULL, FALSE);
|
||||
patchUIValid = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void EditPatchMod::InvalidateTileUI()
|
||||
{
|
||||
if (hTilePanel && selLevel == EP_TILE)
|
||||
{
|
||||
InvalidateRect(hTilePanel, NULL, FALSE);
|
||||
tileUIValid = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void EditPatchMod::InvalidateEdgeUI()
|
||||
{
|
||||
if (hEdgePanel && selLevel == EP_EDGE)
|
||||
{
|
||||
InvalidateRect(hEdgePanel, NULL, FALSE);
|
||||
edgeUIValid = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
BitArray *EditPatchMod::GetLevelSelectionSet(PatchMesh *patch, RPatchMesh *rpatch)
|
||||
{
|
||||
switch (selLevel)
|
||||
{
|
||||
case EP_VERTEX:
|
||||
return &patch->vertSel;
|
||||
|
||||
case EP_PATCH:
|
||||
return &patch->patchSel;
|
||||
|
||||
case EP_EDGE:
|
||||
return &patch->edgeSel;
|
||||
|
||||
case EP_TILE:
|
||||
return &rpatch->tileSel;
|
||||
}
|
||||
nlassert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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::DoVertWeld()
|
||||
{
|
||||
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() > 1)
|
||||
{
|
||||
hadSel = TRUE;
|
||||
if (theHold.Holding())
|
||||
theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "DoVertWeld"));
|
||||
// Call the patch weld function
|
||||
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);
|
||||
}
|
||||
|
||||
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_TOPO, REFMSG_CHANGE);
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
|
||||
}
|
||||
|
||||
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 EditPatchMod::PatchSelChanged()
|
||||
{
|
||||
SelectionChanged();
|
||||
if (hSurfPanel && selLevel == EP_PATCH)
|
||||
InvalidateSurfaceUI();
|
||||
if (hTilePanel && selLevel == EP_TILE)
|
||||
InvalidateTileUI();
|
||||
if (hEdgePanel && selLevel == EP_EDGE)
|
||||
InvalidateEdgeUI();
|
||||
}
|
||||
|
||||
/*
|
||||
class AdvParams
|
||||
{
|
||||
public:
|
||||
TessSubdivStyle mStyle;
|
||||
int mMin, mMax;
|
||||
int mTris;
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void EditPatchMod::LocalDataChanged()
|
||||
{
|
||||
}
|
||||
|
||||
int GetPointIndex (int nVertex, int nPatch, PatchMesh* patch)
|
||||
{
|
||||
for (int n=0; n<4; n++)
|
||||
{
|
||||
if (patch->patches[nPatch].v[n]==nVertex)
|
||||
return n;
|
||||
}
|
||||
nlassert (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Point3 GetInterior (int nPatch, int nInt, PatchMesh* patch)
|
||||
{
|
||||
return patch->vecs[patch->patches[nPatch].interior[nInt]].p;
|
||||
}
|
||||
|
||||
void ResetVert (PatchMesh *patch)
|
||||
{
|
||||
// Make a edge table
|
||||
// Static table to avoid alloc prb
|
||||
CVertexNeighborhood& edgeTab=vertexNeighborhoodGlobal;
|
||||
edgeTab.build (*patch);
|
||||
|
||||
// For each vertices
|
||||
for (int nV=0; nV<patch->numVerts; nV++)
|
||||
{
|
||||
// Selected ?
|
||||
if (patch->vertSel[nV])
|
||||
{
|
||||
Point3 vert=patch->verts[nV].p;
|
||||
Point3 normal (0,0,0);
|
||||
|
||||
// Count of neigbor for vertex n
|
||||
uint listSize=edgeTab.getNeighborCount (nV);
|
||||
|
||||
// List of neigbor
|
||||
const uint* pList=edgeTab.getNeighborList (nV);
|
||||
|
||||
// For each neigbor
|
||||
uint nn;
|
||||
for (nn=0; nn<listSize; nn++)
|
||||
{
|
||||
#if (MAX_RELEASE < 4000)
|
||||
// Compute average plane
|
||||
if (patch->edges[pList[nn]].patch1!=-1)
|
||||
normal+=patch->PatchNormal(patch->edges[pList[nn]].patch1);
|
||||
if (patch->edges[pList[nn]].patch2!=-1)
|
||||
normal+=patch->PatchNormal(patch->edges[pList[nn]].patch2);
|
||||
#else // (MAX_RELEASE <= 4000)
|
||||
// Compute average plane
|
||||
if (patch->edges[pList[nn]].patches[0]!=-1)
|
||||
normal+=patch->PatchNormal(patch->edges[pList[nn]].patches[0]);
|
||||
if (patch->edges[pList[nn]].patches[1]!=-1)
|
||||
normal+=patch->PatchNormal(patch->edges[pList[nn]].patches[1]);
|
||||
#endif // (MAX_RELEASE <= 4000)
|
||||
}
|
||||
|
||||
// Normalize
|
||||
normal=normal.Normalize();
|
||||
|
||||
// Plane
|
||||
float fD=-DotProd(normal, vert);
|
||||
|
||||
// Reset normales
|
||||
float fNorme=0.f;
|
||||
|
||||
// For each neigbor
|
||||
for (nn=0; nn<listSize; nn++)
|
||||
{
|
||||
Point3 vect2=patch->verts[(patch->edges[pList[nn]].v1==nV)?patch->edges[pList[nn]].v2:patch->edges[pList[nn]].v1].p;
|
||||
vect2-=vert;
|
||||
vect2/=3.f;
|
||||
Point3 tmp1=CrossProd (vect2, normal);
|
||||
tmp1=CrossProd (normal, tmp1);
|
||||
tmp1=Normalize(tmp1);
|
||||
int nTang=(patch->edges[pList[nn]].v1==nV)?patch->edges[pList[nn]].vec12:patch->edges[pList[nn]].vec21;
|
||||
patch->vecs[nTang].p=vert+tmp1*DotProd (tmp1,vect2);
|
||||
tmp1=patch->vecs[nTang].p;
|
||||
tmp1-=vert;
|
||||
fNorme+=tmp1.Length();
|
||||
}
|
||||
|
||||
// Renorme new normal
|
||||
/*fNorme/=(float)edgeTab[nV].size();
|
||||
ite=edgeTab[nV].begin();
|
||||
while (ite!=edgeTab[nV].end())
|
||||
{
|
||||
int nTang=(patch->edges[pList[nn]].v1==nV)?patch->edges[pList[nn]].vec12:patch->edges[pList[nn]].vec21;
|
||||
patch->vecs[nTang].p=fNorme*(Normalize(patch->vecs[nTang].p-vert))+vert;
|
||||
|
||||
ite++;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
patch->computeInteriors();
|
||||
patch->InvalidateGeomCache ();
|
||||
}
|
@ -1,425 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
#define PROMPT_TIME 2000
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
extern int attachReorient;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
static void AddPatches(int type, PatchMesh *patch, RPatchMesh *rpatch, BOOL postWeld)
|
||||
{
|
||||
if (!patch->edgeSel.NumberSet())
|
||||
return; // Nothing to do!
|
||||
|
||||
int lastVert = patch->getNumVerts();
|
||||
int edges = patch->getNumEdges();
|
||||
|
||||
if (type==PATCH_TRI)
|
||||
MessageBox (NULL, "Rykol tools", "C'est pas cool les tripatches...", MB_OK|MB_ICONEXCLAMATION);
|
||||
|
||||
// Add a patch of the desired type to each selected edge that doesn't have two patches atatched!
|
||||
for (int i = 0; i < edges; ++i)
|
||||
{
|
||||
if (patch->edgeSel[i])
|
||||
{
|
||||
PatchEdge &edge = patch->edges[i];
|
||||
#if (MAX_RELEASE < 4000)
|
||||
int nFirstPatch=edge.patch1;
|
||||
if (edge.patch2 < 0)
|
||||
#else // (MAX_RELEASE < 4000)
|
||||
int nFirstPatch=edge.patches[0];
|
||||
if (edge.patches[1] < 0)
|
||||
#endif // (MAX_RELEASE < 4000)
|
||||
{
|
||||
int verts = patch->getNumVerts();
|
||||
int vecs = patch->getNumVecs();
|
||||
int patches = patch->getNumPatches();
|
||||
patch->setNumPatches(patches + 1, TRUE); // Add a patch
|
||||
patch->patches[patches].SetType(type); // Make it the type we want
|
||||
patch->setNumVerts(verts + type - 2, TRUE); // Add the appropriate number of verts
|
||||
rpatch->SetNumVerts(verts + type - 2); // And the appropriate vector count
|
||||
patch->setNumVecs(vecs +(type - 1) * 2 + type, TRUE); // And the appropriate vector count
|
||||
Point3 p1 = patch->verts[edge.v1].p;
|
||||
Point3 p2 = patch->verts[edge.v2].p;
|
||||
Point3 v12 = patch->vecs[edge.vec12].p;
|
||||
Point3 v21 = patch->vecs[edge.vec21].p;
|
||||
Point3 edgeCenter =(p1 + p2) / 2.0f;
|
||||
// Load up the patch with the correct vert/vector indices
|
||||
#if (MAX_RELEASE < 4000)
|
||||
Patch &spatch = patch->patches[edge.patch1];
|
||||
#else // (MAX_RELEASE < 4000)
|
||||
Patch &spatch = patch->patches[edge.patches[0]];
|
||||
#endif // (MAX_RELEASE < 4000)
|
||||
Patch &dpatch = patch->patches[patches];
|
||||
switch (type)
|
||||
{
|
||||
case PATCH_TRI:
|
||||
dpatch.setVerts(edge.v2, edge.v1, verts);
|
||||
dpatch.setVecs(edge.vec21, edge.vec12, vecs, vecs + 1, vecs + 2, vecs + 3);
|
||||
dpatch.setInteriors(vecs + 4, vecs + 5, vecs + 6);
|
||||
switch (spatch.type)
|
||||
{
|
||||
case PATCH_TRI:
|
||||
{ // Tri from Tri
|
||||
// Find the opposite vertex in the source triangle
|
||||
int opposite, o2a, o1a;
|
||||
if (spatch.edge[0] == i)
|
||||
{
|
||||
opposite = 2;
|
||||
o1a = 5;
|
||||
o2a = 2;
|
||||
}
|
||||
else
|
||||
if (spatch.edge[1] == i)
|
||||
{
|
||||
opposite = 0;
|
||||
o1a = 1;
|
||||
o2a = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
opposite = 1;
|
||||
o1a = 3;
|
||||
o2a = 0;
|
||||
}
|
||||
// Compute the new vert position
|
||||
Point3 oppVec = edgeCenter - patch->verts[spatch.v[opposite]].p;
|
||||
float oppLen = Length(oppVec);
|
||||
if (oppLen == 0.0f)
|
||||
{
|
||||
oppVec = Point3(0, 0, 1);
|
||||
oppLen = 1.0f;
|
||||
}
|
||||
Point3 v1a = patch->vecs[spatch.vec[o1a]].p - p1;
|
||||
Point3 v2a = patch->vecs[spatch.vec[o2a]].p - p2;
|
||||
Point3 n1a, n2a;
|
||||
if (Length(v1a) > 0.0f)
|
||||
n1a = Normalize(v1a);
|
||||
else
|
||||
n1a = Normalize(oppVec);
|
||||
if (Length(v2a) > 0.0f)
|
||||
n2a = Normalize(v2a);
|
||||
else
|
||||
n2a = Normalize(oppVec);
|
||||
|
||||
// Build a composite vector based on the two edge vectors
|
||||
Point3 compVec = Normalize((n1a + n2a) / 2.0f);
|
||||
|
||||
// Create the new vertex
|
||||
Point3 newPos = edgeCenter - compVec * oppLen;
|
||||
patch->verts[verts].p = newPos;
|
||||
|
||||
// Compute the vectors
|
||||
patch->vecs[vecs].p = p1 - v1a;
|
||||
patch->vecs[vecs + 1].p = newPos -(newPos - p1) / 3.0f;
|
||||
patch->vecs[vecs + 2].p = newPos -(newPos - p2) / 3.0f;
|
||||
patch->vecs[vecs + 3].p = p2 - v2a;
|
||||
}
|
||||
break;
|
||||
case PATCH_QUAD:
|
||||
{ // Tri from Quad
|
||||
// Find the opposite edge verts in the source quad
|
||||
int opposite1, opposite2, o1a, o2a;
|
||||
if (spatch.edge[0] == i)
|
||||
{
|
||||
opposite1 = 2;
|
||||
opposite2 = 3;
|
||||
o1a = 7;
|
||||
o2a = 2;
|
||||
}
|
||||
else
|
||||
if (spatch.edge[1] == i)
|
||||
{
|
||||
opposite1 = 3;
|
||||
opposite2 = 0;
|
||||
o1a = 1;
|
||||
o2a = 4;
|
||||
}
|
||||
else
|
||||
if (spatch.edge[2] == i)
|
||||
{
|
||||
opposite1 = 0;
|
||||
opposite2 = 1;
|
||||
o1a = 3;
|
||||
o2a = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
opposite1 = 1;
|
||||
opposite2 = 2;
|
||||
o1a = 5;
|
||||
o2a = 0;
|
||||
}
|
||||
// Compute the new vert position
|
||||
Point3 otherCenter =(patch->verts[spatch.v[opposite1]].p + patch->verts[spatch.v[opposite2]].p) / 2.0f;
|
||||
Point3 oppVec = edgeCenter - otherCenter;
|
||||
float oppLen = Length(oppVec);
|
||||
if (oppLen == 0.0f)
|
||||
{
|
||||
oppVec = Point3(0, 0, 1);
|
||||
oppLen = 1.0f;
|
||||
}
|
||||
Point3 v1a = patch->vecs[spatch.vec[o1a]].p - p1;
|
||||
Point3 v2a = patch->vecs[spatch.vec[o2a]].p - p2;
|
||||
Point3 n1a, n2a;
|
||||
if (Length(v1a) > 0.0f)
|
||||
n1a = Normalize(v1a);
|
||||
else
|
||||
n1a = Normalize(oppVec);
|
||||
if (Length(v2a) > 0.0f)
|
||||
n2a = Normalize(v2a);
|
||||
else
|
||||
n2a = Normalize(oppVec);
|
||||
|
||||
// Build a composite vector based on the two edge vectors
|
||||
Point3 compVec = Normalize((n1a + n2a) / 2.0f);
|
||||
|
||||
// Create the new vertex
|
||||
Point3 newPos = edgeCenter - compVec * oppLen;
|
||||
patch->verts[verts].p = newPos;
|
||||
|
||||
// Compute the vectors
|
||||
patch->vecs[vecs].p = p1 - v1a;
|
||||
patch->vecs[vecs + 1].p = newPos -(newPos - p1) / 3.0f;
|
||||
patch->vecs[vecs + 2].p = newPos -(newPos - p2) / 3.0f;
|
||||
patch->vecs[vecs + 3].p = p2 - v2a;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PATCH_QUAD:
|
||||
dpatch.setVerts(edge.v2, edge.v1, verts, verts + 1);
|
||||
dpatch.setVecs(edge.vec21, edge.vec12, vecs, vecs + 1, vecs + 2, vecs + 3, vecs + 4, vecs + 5);
|
||||
dpatch.setInteriors(vecs + 6, vecs + 7, vecs + 8, vecs + 9);
|
||||
switch (spatch.type)
|
||||
{
|
||||
case PATCH_TRI:
|
||||
{ // Quad from Tri
|
||||
// Find the opposite vertex in the source triangle
|
||||
int opposite, o2a, o1a;
|
||||
if (spatch.edge[0] == i)
|
||||
{
|
||||
opposite = 2;
|
||||
o1a = 5;
|
||||
o2a = 2;
|
||||
}
|
||||
else
|
||||
if (spatch.edge[1] == i)
|
||||
{
|
||||
opposite = 0;
|
||||
o1a = 1;
|
||||
o2a = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
opposite = 1;
|
||||
o1a = 3;
|
||||
o2a = 0;
|
||||
}
|
||||
|
||||
Point3 oppVec = edgeCenter - patch->verts[spatch.v[opposite]].p;
|
||||
float oppLen = Length(oppVec);
|
||||
if (oppLen == 0.0f)
|
||||
{
|
||||
oppVec = Point3(0, 0, 1);
|
||||
oppLen = 1.0f;
|
||||
}
|
||||
Point3 v1a = patch->vecs[spatch.vec[o1a]].p - p1;
|
||||
Point3 v2a = patch->vecs[spatch.vec[o2a]].p - p2;
|
||||
Point3 n1a, n2a;
|
||||
if (Length(v1a) > 0.0f)
|
||||
n1a = Normalize(v1a);
|
||||
else
|
||||
n1a = Normalize(oppVec);
|
||||
if (Length(v2a) > 0.0f)
|
||||
n2a = Normalize(v2a);
|
||||
else
|
||||
n2a = Normalize(oppVec);
|
||||
|
||||
// Compute the new vert positions
|
||||
Point3 newPos1 = p1 - n1a * oppLen;
|
||||
Point3 newPos2 = p2 - n2a * oppLen;
|
||||
patch->verts[verts].p = newPos1;
|
||||
patch->verts[verts + 1].p = newPos2;
|
||||
// Compute the vectors
|
||||
patch->vecs[vecs].p = p1 - v1a;
|
||||
patch->vecs[vecs + 1].p = newPos1 -(newPos1 - p1) / 3.0f;
|
||||
patch->vecs[vecs + 2].p = newPos1 +(v12 - p1);
|
||||
patch->vecs[vecs + 3].p = newPos2 +(v21 - p2);
|
||||
patch->vecs[vecs + 4].p = newPos2 +(p2 - newPos2) / 3.0f;
|
||||
patch->vecs[vecs + 5].p = p2 - v2a;
|
||||
}
|
||||
break;
|
||||
case PATCH_QUAD:
|
||||
{ // Quad from Quad
|
||||
// Find the opposite edge verts in the source quad
|
||||
int opposite1, opposite2, o1a, o2a;
|
||||
if (spatch.edge[0] == i)
|
||||
{
|
||||
opposite1 = 2;
|
||||
opposite2 = 3;
|
||||
o1a = 7;
|
||||
o2a = 2;
|
||||
}
|
||||
else
|
||||
if (spatch.edge[1] == i)
|
||||
{
|
||||
opposite1 = 3;
|
||||
opposite2 = 0;
|
||||
o1a = 1;
|
||||
o2a = 4;
|
||||
}
|
||||
else
|
||||
if (spatch.edge[2] == i)
|
||||
{
|
||||
opposite1 = 0;
|
||||
opposite2 = 1;
|
||||
o1a = 3;
|
||||
o2a = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
opposite1 = 1;
|
||||
opposite2 = 2;
|
||||
o1a = 5;
|
||||
o2a = 0;
|
||||
}
|
||||
|
||||
Point3 otherCenter =(patch->verts[spatch.v[opposite1]].p + patch->verts[spatch.v[opposite2]].p) / 2.0f;
|
||||
Point3 oppVec = edgeCenter - otherCenter;
|
||||
float oppLen = Length(oppVec);
|
||||
if (oppLen == 0.0f)
|
||||
{
|
||||
oppVec = Point3(0, 0, 1);
|
||||
oppLen = 1.0f;
|
||||
}
|
||||
Point3 v1a = patch->vecs[spatch.vec[o1a]].p - p1;
|
||||
Point3 v2a = patch->vecs[spatch.vec[o2a]].p - p2;
|
||||
Point3 n1a, n2a;
|
||||
if (Length(v1a) > 0.0f)
|
||||
n1a = Normalize(v1a);
|
||||
else
|
||||
n1a = Normalize(oppVec);
|
||||
if (Length(v2a) > 0.0f)
|
||||
n2a = Normalize(v2a);
|
||||
else
|
||||
n2a = Normalize(oppVec);
|
||||
|
||||
// Compute the new vert position
|
||||
Point3 newPos1 = p1 - n1a * oppLen;
|
||||
Point3 newPos2 = p2 - n2a * oppLen;
|
||||
patch->verts[verts].p = newPos1;
|
||||
patch->verts[verts + 1].p = newPos2;
|
||||
|
||||
// Compute the vectors
|
||||
patch->vecs[vecs].p = p1 - v1a;
|
||||
patch->vecs[vecs + 1].p = newPos1 -(newPos1 - p1) / 3.0f;
|
||||
patch->vecs[vecs + 2].p = newPos1 +(v12 - p1);
|
||||
patch->vecs[vecs + 3].p = newPos2 +(v21 - p2);
|
||||
patch->vecs[vecs + 4].p = newPos2 +(p2 - newPos2) / 3.0f;
|
||||
patch->vecs[vecs + 5].p = p2 - v2a;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
rpatch->AddPatch (i, nFirstPatch, patch);
|
||||
}
|
||||
}
|
||||
}
|
||||
patch->computeInteriors();
|
||||
patch->buildLinkages();
|
||||
// This step welds all new identical verts
|
||||
if (postWeld &&(patch->getNumVerts() != lastVert))
|
||||
patch->Weld(0.0f, TRUE, lastVert);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
BOOL PatchAddRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (reRecord)
|
||||
{
|
||||
oldPatch = *patch;
|
||||
roldPatch = *rpatch;
|
||||
}
|
||||
AddPatches(type, patch, rpatch, postWeld);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::DoPatchAdd(int type)
|
||||
{
|
||||
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, "DoPatchAdd"));
|
||||
// Call the patch add function
|
||||
AddPatches(type, patch, rpatch, TRUE);
|
||||
patchData->UpdateChanges(patch, rpatch);
|
||||
patchData->TempData(this)->Invalidate(PART_TOPO);
|
||||
}
|
||||
patchData->SetFlag(EPD_BEENDONE, TRUE);
|
||||
}
|
||||
|
||||
if (holdNeeded)
|
||||
{
|
||||
ResolveTopoChanges();
|
||||
theHold.Accept(GetString(IDS_TH_PATCHADD));
|
||||
}
|
||||
else
|
||||
{
|
||||
ip->DisplayTempPrompt(GetString(IDS_TH_NOVALIDEDGESSEL), PROMPT_TIME);
|
||||
theHold.End();
|
||||
}
|
||||
|
||||
nodes.DisposeTemporary();
|
||||
ClearPatchDataFlag(mcList, EPD_BEENDONE);
|
||||
NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
|
||||
}
|
||||
|
@ -1,276 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
#define PROMPT_TIME 2000
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
extern int attachReorient;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
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;
|
||||
}
|
@ -1,382 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
#define PROMPT_TIME 2000
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
int EPM_BevelMouseProc::proc(HWND hwnd, int msg, int point, int flags, IPoint2 m)
|
||||
{
|
||||
ViewExp *vpt = ip->GetViewport(hwnd);
|
||||
Point3 p0, p1;
|
||||
ISpinnerControl *spin;
|
||||
int ln, ln2;
|
||||
IPoint2 m2;
|
||||
float amount;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case MOUSE_PROPCLICK:
|
||||
ip->SetStdCommandMode(CID_OBJMOVE);
|
||||
break;
|
||||
|
||||
case MOUSE_POINT:
|
||||
if (point == 0)
|
||||
{
|
||||
po->BeginExtrude(ip->GetTime());
|
||||
om = m;
|
||||
}
|
||||
else if (point == 1)
|
||||
{
|
||||
po->EndExtrude(ip->GetTime(), TRUE);
|
||||
po->BeginBevel(ip->GetTime());
|
||||
om = m;
|
||||
}
|
||||
else
|
||||
{
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_END);
|
||||
po->EndBevel(ip->GetTime(), TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case MOUSE_MOVE:
|
||||
if (point == 1)
|
||||
{
|
||||
p0 = vpt->MapScreenToView(om, float(-200));
|
||||
// sca 1999.02.24: find worldspace point with om's x value and m's y value
|
||||
m2.x = om.x;
|
||||
m2.y = m.y;
|
||||
p1 = vpt->MapScreenToView(m2, float(-200));
|
||||
amount = Length(p1 - p0);
|
||||
ln = IsDlgButtonChecked(po->hOpsPanel, IDC_EM_EXTYPE_B);
|
||||
if (om.y < m.y)
|
||||
amount *= -1.0f;
|
||||
po->Extrude(ip->GetTime(), amount, ln);
|
||||
|
||||
spin = GetISpinner(GetDlgItem(po->hOpsPanel, IDC_EP_EXTRUDESPINNER));
|
||||
if (spin)
|
||||
{
|
||||
spin->SetValue(amount, FALSE);
|
||||
ReleaseISpinner(spin);
|
||||
}
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_INTERACTIVE);
|
||||
}
|
||||
else if (point == 2)
|
||||
{
|
||||
p0 = vpt->MapScreenToView(om, float(-200));
|
||||
// sca 1999.02.24: find worldspace point with om's x value and m's y value
|
||||
m2.x = om.x;
|
||||
m2.y = m.y;
|
||||
p1 = vpt->MapScreenToView(m2, float(-200));
|
||||
if (IsDlgButtonChecked(po->hOpsPanel, IDC_EP_SM_SMOOTH))
|
||||
ln = 0;
|
||||
else if (IsDlgButtonChecked(po->hOpsPanel, IDC_EP_SM_SMOOTH2))
|
||||
ln = 1;
|
||||
else if (IsDlgButtonChecked(po->hOpsPanel, IDC_EP_SM_SMOOTH3))
|
||||
ln = 2;
|
||||
|
||||
if (IsDlgButtonChecked(po->hOpsPanel, IDC_EP_SM_SMOOTH4))
|
||||
ln2 = 0;
|
||||
else if (IsDlgButtonChecked(po->hOpsPanel, IDC_EP_SM_SMOOTH5))
|
||||
ln2 = 1;
|
||||
else if (IsDlgButtonChecked(po->hOpsPanel, IDC_EP_SM_SMOOTH6))
|
||||
ln2 = 2;
|
||||
|
||||
amount = Length(p1 - p0);
|
||||
if (om.y < m.y)
|
||||
amount *= -1.0f;
|
||||
po->Bevel(ip->GetTime(), amount, ln, ln2);
|
||||
|
||||
spin = GetISpinner(GetDlgItem(po->hOpsPanel, IDC_EP_OUTLINESPINNER));
|
||||
if (spin)
|
||||
{
|
||||
spin->SetValue(amount, FALSE);
|
||||
ReleaseISpinner(spin);
|
||||
}
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_INTERACTIVE);
|
||||
}
|
||||
break;
|
||||
|
||||
case MOUSE_ABORT:
|
||||
if (point == 1)
|
||||
po->EndExtrude(ip->GetTime(), FALSE);
|
||||
else if (point>1)
|
||||
po->EndBevel(ip->GetTime(), FALSE);
|
||||
|
||||
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_END);
|
||||
break;
|
||||
}
|
||||
|
||||
if (vpt)
|
||||
ip->ReleaseViewport(vpt);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
HCURSOR EPM_BevelSelectionProcessor::GetTransformCursor()
|
||||
{
|
||||
static HCURSOR hCur = NULL;
|
||||
if (!hCur)
|
||||
hCur = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_BEVEL));
|
||||
return hCur;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
void EPM_BevelCMode::EnterMode()
|
||||
{
|
||||
if (!po->hOpsPanel)
|
||||
return;
|
||||
ICustButton *but = GetICustButton(GetDlgItem(po->hOpsPanel, IDC_EP_BEVEL));
|
||||
but->SetCheck(TRUE);
|
||||
ReleaseICustButton(but);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
void EPM_BevelCMode::ExitMode()
|
||||
{
|
||||
if (!po->hOpsPanel)
|
||||
return;
|
||||
ICustButton *but = GetICustButton(GetDlgItem(po->hOpsPanel, IDC_EP_BEVEL));
|
||||
but->SetCheck(FALSE);
|
||||
ReleaseICustButton(but);
|
||||
ISpinnerControl *spin;
|
||||
spin = GetISpinner(GetDlgItem(po->hOpsPanel, IDC_EP_OUTLINESPINNER));
|
||||
if (spin)
|
||||
{
|
||||
spin->SetValue(0.0f, FALSE);
|
||||
ReleaseISpinner(spin);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::DoBevel()
|
||||
{
|
||||
|
||||
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->patchSel.NumberSet())
|
||||
{
|
||||
|
||||
altered = holdNeeded = TRUE;
|
||||
if (theHold.Holding())
|
||||
theHold.Put(new PatchRestore(patchData, this, patch, rpatch));
|
||||
// Call the vertex type change function
|
||||
patch->CreateBevel();
|
||||
// patch->CreateExtrusion();
|
||||
// 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);
|
||||
|
||||
/*
|
||||
theHold.Begin();
|
||||
patch.RecordTopologyTags();
|
||||
POPatchGenRecord *rec = new POPatchGenRecord(this);
|
||||
if (theHold.Holding())
|
||||
theHold.Put(new PatchObjectRestore(this, rec));
|
||||
|
||||
patch.CreateBevel();
|
||||
|
||||
ResolveTopoChanges();
|
||||
theHold.Accept(GetResString(IDS_TH_PATCHADD));
|
||||
|
||||
patch.InvalidateGeomCache();
|
||||
InvalidateMesh();
|
||||
|
||||
NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
|
||||
*/
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::BeginBevel(TimeValue t)
|
||||
{
|
||||
if (inBevel)
|
||||
return;
|
||||
inBevel = TRUE;
|
||||
theHold.SuperBegin();
|
||||
DoBevel();
|
||||
// PlugControllersSel(t,sel);
|
||||
theHold.Begin();
|
||||
}
|
||||
|
||||
void EditPatchMod::EndBevel(TimeValue t, BOOL accept)
|
||||
{
|
||||
if (!ip)
|
||||
return;
|
||||
if (!inBevel)
|
||||
return;
|
||||
inBevel = FALSE;
|
||||
// TempData()->freeBevelInfo();
|
||||
ISpinnerControl *spin;
|
||||
|
||||
spin = GetISpinner(GetDlgItem(hOpsPanel, IDC_EP_OUTLINESPINNER));
|
||||
if (spin)
|
||||
{
|
||||
spin->SetValue(0, FALSE);
|
||||
ReleaseISpinner(spin);
|
||||
}
|
||||
|
||||
|
||||
theHold.Accept(GetString(IDS_EM_BEVEL));
|
||||
if (accept)
|
||||
theHold.SuperAccept(GetString(IDS_EM_BEVEL));
|
||||
else theHold.SuperCancel();
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::Bevel(TimeValue t, float amount, BOOL smoothStart, BOOL smoothEnd)
|
||||
{
|
||||
if (!inBevel)
|
||||
return;
|
||||
|
||||
|
||||
ModContextList mcList;
|
||||
INodeTab nodes;
|
||||
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->patchSel.NumberSet())
|
||||
{
|
||||
|
||||
altered = holdNeeded = TRUE;
|
||||
if (theHold.Holding())
|
||||
theHold.Put(new PatchRestore(patchData, this, patch, rpatch));
|
||||
// Call the vertex type change function
|
||||
patch->Bevel(amount, smoothStart, smoothEnd);
|
||||
// patch->MoveNormal(amount,useLocalNorms);
|
||||
// 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);
|
||||
/*
|
||||
theHold.Restore();
|
||||
patch.Bevel(amount, smoothStart, smoothEnd);
|
||||
|
||||
patch.InvalidateGeomCache();
|
||||
InvalidateMesh();
|
||||
|
||||
NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
|
||||
*/
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -1,541 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
#define PROMPT_TIME 2000
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
extern void DeletePatchParts(PatchMesh *patch, RPatchMesh *rpatch, BitArray &delVerts, BitArray &delPatches);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::DoDeleteSelected()
|
||||
{
|
||||
switch (GetSubobjectLevel())
|
||||
{
|
||||
case EP_VERTEX:
|
||||
DoVertDelete();
|
||||
break;
|
||||
case EP_EDGE:
|
||||
DoEdgeDelete();
|
||||
break;
|
||||
case EP_PATCH:
|
||||
DoPatchDelete();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
static void DeleteSelPatches(PatchMesh *patch, RPatchMesh *rpatch)
|
||||
{
|
||||
if (!patch->patchSel.NumberSet())
|
||||
return; // Nothing to do!
|
||||
|
||||
int patches = patch->getNumPatches();
|
||||
int verts = patch->getNumVerts();
|
||||
|
||||
// Tag the patches that are selected
|
||||
BitArray delPatches(patches);
|
||||
delPatches = patch->patchSel;
|
||||
|
||||
BitArray delVerts(verts);
|
||||
delVerts.ClearAll();
|
||||
|
||||
DeletePatchParts(patch, rpatch, delVerts, delPatches);
|
||||
patch->computeInteriors();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
BOOL PatchDeleteRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (reRecord)
|
||||
{
|
||||
oldPatch = *patch;
|
||||
roldPatch = *rpatch;
|
||||
}
|
||||
DeleteSelPatches(patch, rpatch);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::DoPatchDelete()
|
||||
{
|
||||
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->patchSel.NumberSet())
|
||||
{
|
||||
altered = holdNeeded = 1;
|
||||
if (theHold.Holding())
|
||||
theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "DoPatchDelete"));
|
||||
// Call the patch delete function
|
||||
DeleteSelPatches(patch, rpatch);
|
||||
patchData->UpdateChanges(patch, rpatch);
|
||||
patchData->TempData(this)->Invalidate(PART_TOPO);
|
||||
}
|
||||
patchData->SetFlag(EPD_BEENDONE, TRUE);
|
||||
}
|
||||
|
||||
if (holdNeeded)
|
||||
{
|
||||
ResolveTopoChanges();
|
||||
theHold.Accept(GetString(IDS_TH_PATCHDELETE));
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void DeleteSelVerts(PatchMesh *patch, RPatchMesh *rpatch)
|
||||
{
|
||||
if (!patch->vertSel.NumberSet())
|
||||
return; // Nothing to do!
|
||||
|
||||
int patches = patch->getNumPatches();
|
||||
int verts = patch->getNumVerts();
|
||||
|
||||
// Tag the patches that use selected vertices
|
||||
BitArray delPatches(patches);
|
||||
delPatches.ClearAll();
|
||||
for (int i = 0; i < patches; ++i)
|
||||
{
|
||||
Patch& p = patch->patches[i];
|
||||
for (int j = 0; j < p.type; ++j)
|
||||
{
|
||||
if (patch->vertSel[p.v[j]])
|
||||
{
|
||||
delPatches.Set(i);
|
||||
goto next_patch;
|
||||
}
|
||||
}
|
||||
next_patch:;
|
||||
}
|
||||
|
||||
BitArray delVerts(verts);
|
||||
delVerts = patch->vertSel;
|
||||
DeletePatchParts(patch, rpatch, delVerts, delPatches);
|
||||
patch->computeInteriors();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Vertex Delete modifier method
|
||||
void EditPatchMod::DoVertDelete()
|
||||
{
|
||||
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->vertSel.NumberSet())
|
||||
{
|
||||
altered = holdNeeded = 1;
|
||||
if (theHold.Holding())
|
||||
theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "DoVertDelete"));
|
||||
// Call the vertex delete function
|
||||
DeleteSelVerts(patch, rpatch);
|
||||
patchData->UpdateChanges(patch, rpatch);
|
||||
patchData->TempData(this)->Invalidate(PART_TOPO);
|
||||
}
|
||||
patchData->SetFlag(EPD_BEENDONE, TRUE);
|
||||
}
|
||||
|
||||
if (holdNeeded)
|
||||
{
|
||||
ResolveTopoChanges();
|
||||
theHold.Accept(GetString(IDS_TH_VERTDELETE));
|
||||
}
|
||||
else
|
||||
{
|
||||
ip->DisplayTempPrompt(GetString(IDS_TH_NOVERTSSEL), 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);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Deletes any vertices tagged, also any patches tagged. Automatically deletes the vectors that
|
||||
// are deleted as a result of the patch deletion and sweeps any vertices floating in space.
|
||||
|
||||
void DeletePatchParts(PatchMesh *patch, RPatchMesh *rpatch, BitArray &delVerts, BitArray &delPatches)
|
||||
{
|
||||
int patches = patch->getNumPatches();
|
||||
int verts = patch->getNumVerts();
|
||||
int vecs = patch->getNumVecs();
|
||||
int dest;
|
||||
|
||||
// We treat vectors specially in order to clean up after welds. First, we tag 'em all,
|
||||
// then untag only those on unselected patches so that any dangling vectors will be deleted.
|
||||
BitArray delVectors(vecs);
|
||||
delVectors.SetAll();
|
||||
|
||||
// Untag vectors that are on nondeleted patches
|
||||
int i;
|
||||
for (i = 0; i < patches; ++i)
|
||||
{
|
||||
if (!delPatches[i])
|
||||
{
|
||||
Patch& p = patch->patches[i];
|
||||
int j;
|
||||
for (j = 0; j <(p.type * 2); ++j)
|
||||
{
|
||||
delVectors.Clear(p.vec[j]);
|
||||
}
|
||||
for (j = 0; j < p.type; ++j)
|
||||
delVectors.Clear(p.interior[j]);
|
||||
}
|
||||
}
|
||||
|
||||
// Make a table of vertices that are still in use -- Used to
|
||||
// delete those vertices which are floating, unused, in space.
|
||||
BitArray usedVerts(verts);
|
||||
usedVerts.ClearAll();
|
||||
for (i = 0; i < patches; ++i)
|
||||
{
|
||||
if (!delPatches[i])
|
||||
{
|
||||
Patch& p = patch->patches[i];
|
||||
for (int j = 0; j < p.type; ++j)
|
||||
{
|
||||
usedVerts.Set(p.v[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < verts; ++i)
|
||||
{
|
||||
if (!usedVerts[i])
|
||||
delVerts.Set(i);
|
||||
}
|
||||
|
||||
// If we have texture vertices, handle them, too
|
||||
for (int chan = 0; chan < patch->getNumMaps(); ++chan)
|
||||
{
|
||||
int tverts = patch->numTVerts[chan];
|
||||
if (tverts && patch->tvPatches[chan])
|
||||
{
|
||||
BitArray delTVerts(tverts);
|
||||
delTVerts.SetAll();
|
||||
for (i = 0; i < patches; ++i)
|
||||
{
|
||||
if (!delPatches[i])
|
||||
{
|
||||
Patch& p = patch->patches[i];
|
||||
TVPatch& tp = patch->tvPatches[chan][i];
|
||||
for (int j = 0; j < p.type; ++j)
|
||||
delTVerts.Clear(tp.tv[j]);
|
||||
}
|
||||
}
|
||||
// Got the list of tverts to delete -- now delete 'em
|
||||
// Build a table of redirected texture vertex indices
|
||||
int newTVerts = tverts - delTVerts.NumberSet();
|
||||
IntTab tVertIndex;
|
||||
tVertIndex.SetCount(tverts);
|
||||
UVVert *newTVertArray = new UVVert[newTVerts];
|
||||
dest = 0;
|
||||
for (i = 0; i < tverts; ++i)
|
||||
{
|
||||
if (!delTVerts[i])
|
||||
{
|
||||
newTVertArray[dest] = patch->tVerts[chan][i];
|
||||
tVertIndex[i] = dest++;
|
||||
}
|
||||
}
|
||||
delete[] patch->tVerts[chan];
|
||||
#if MAX_RELEASE <= 3100
|
||||
patch->tVerts[chan] = newTVertArray;
|
||||
#else
|
||||
*(patch->tVerts[chan]) = *newTVertArray;
|
||||
#endif
|
||||
patch->numTVerts[chan] = newTVerts;
|
||||
// Now, copy the untagged texture patches to a new array
|
||||
// While you're at it, redirect the vertex indices
|
||||
int newTVPatches = patches - delPatches.NumberSet();
|
||||
TVPatch *newArray = new TVPatch[newTVPatches];
|
||||
dest = 0;
|
||||
for (i = 0; i < patches; ++i)
|
||||
{
|
||||
if (!delPatches[i])
|
||||
{
|
||||
Patch& p = patch->patches[i];
|
||||
TVPatch& tp = newArray[dest++];
|
||||
tp = patch->tvPatches[chan][i];
|
||||
for (int j = 0; j < p.type; ++j)
|
||||
tp.tv[j] = tVertIndex[tp.tv[j]];
|
||||
}
|
||||
}
|
||||
delete[] patch->tvPatches[chan];
|
||||
patch->tvPatches[chan] = newArray;;
|
||||
}
|
||||
}
|
||||
|
||||
// Build a table of redirected vector indices
|
||||
IntTab vecIndex;
|
||||
vecIndex.SetCount(vecs);
|
||||
int newVectors = vecs - delVectors.NumberSet();
|
||||
PatchVec *newVecArray = new PatchVec[newVectors];
|
||||
dest = 0;
|
||||
for (i = 0; i < vecs; ++i)
|
||||
{
|
||||
if (!delVectors[i])
|
||||
{
|
||||
newVecArray[dest] = patch->vecs[i];
|
||||
vecIndex[i] = dest++;
|
||||
}
|
||||
else
|
||||
vecIndex[i] = -1;
|
||||
}
|
||||
delete[] patch->vecs;
|
||||
patch->vecs = newVecArray;
|
||||
patch->numVecs = newVectors;
|
||||
|
||||
// Build a table of redirected vertex indices
|
||||
int newVerts = verts - delVerts.NumberSet();
|
||||
IntTab vertIndex;
|
||||
vertIndex.SetCount(verts);
|
||||
PatchVert *newVertArray = new PatchVert[newVerts];
|
||||
BitArray newVertSel(newVerts);
|
||||
newVertSel.ClearAll();
|
||||
dest = 0;
|
||||
for (i = 0; i < verts; ++i)
|
||||
{
|
||||
if (!delVerts[i])
|
||||
{
|
||||
newVertArray[dest] = patch->verts[i];
|
||||
newVertSel.Set(dest, patch->vertSel[i]);
|
||||
// redirect & adjust attached vector list
|
||||
PatchVert& v = newVertArray[dest];
|
||||
for (int j = 0; j < v.vectors.Count(); ++j)
|
||||
{
|
||||
v.vectors[j] = vecIndex[v.vectors[j]];
|
||||
if (v.vectors[j] < 0)
|
||||
{
|
||||
v.vectors.Delete(j, 1);
|
||||
j--; // realign index
|
||||
}
|
||||
}
|
||||
vertIndex[i] = dest++;
|
||||
}
|
||||
}
|
||||
delete[] patch->verts;
|
||||
patch->verts = newVertArray;
|
||||
patch->numVerts = newVerts;
|
||||
patch->vertSel = newVertSel;
|
||||
|
||||
// Now, copy the untagged patches to a new array
|
||||
// While you're at it, redirect the vertex and vector indices
|
||||
int newPatches = patches - delPatches.NumberSet();
|
||||
Patch *newArray = new Patch[newPatches];
|
||||
BitArray newPatchSel(newPatches);
|
||||
newPatchSel.ClearAll();
|
||||
dest = 0;
|
||||
for (i = 0; i < patches; ++i)
|
||||
{
|
||||
if (!delPatches[i])
|
||||
{
|
||||
newArray[dest] = patch->patches[i];
|
||||
Patch& p = newArray[dest];
|
||||
int j;
|
||||
for (j = 0; j < p.type; ++j)
|
||||
p.v[j] = vertIndex[p.v[j]];
|
||||
for (j = 0; j <(p.type * 2); ++j)
|
||||
p.vec[j] = vecIndex[p.vec[j]];
|
||||
for (j = 0; j < p.type; ++j)
|
||||
p.interior[j] = vecIndex[p.interior[j]];
|
||||
newPatchSel.Set(dest++, patch->patchSel[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Rebuild info in rpatch
|
||||
rpatch->DeleteAndSweep (delVerts, delPatches, *patch);
|
||||
|
||||
delete[] patch->patches;
|
||||
patch->patches = newArray;;
|
||||
patch->numPatches = newPatches;
|
||||
patch->patchSel.SetSize(newPatches, TRUE);
|
||||
patch->patchSel = newPatchSel;
|
||||
patch->buildLinkages();
|
||||
}
|
||||
|
@ -1,297 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
#define PROMPT_TIME 2000
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
extern void DeletePatchParts(PatchMesh *patch, RPatchMesh *rpatch, BitArray &delVerts, BitArray &delPatches);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
static TSTR detachName;
|
||||
|
||||
static BOOL CALLBACK DetachDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
TCHAR tempName[256];
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
SetDlgItemText(hDlg, IDC_DETACH_NAME, detachName);
|
||||
SetFocus(GetDlgItem(hDlg, IDC_DETACH_NAME));
|
||||
return FALSE;
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDOK:
|
||||
GetDlgItemText(hDlg, IDC_DETACH_NAME, tempName, 255);
|
||||
detachName = TSTR(tempName);
|
||||
EndDialog(hDlg, 1);
|
||||
return TRUE;
|
||||
case IDCANCEL:
|
||||
EndDialog(hDlg, 0);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static int GetDetachOptions(IObjParam *ip, TSTR& newName)
|
||||
{
|
||||
detachName = newName;
|
||||
ip->MakeNameUnique(detachName);
|
||||
if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_DETACH), ip->GetMAXHWnd(), (DLGPROC)DetachDialogProc) == 1)
|
||||
{
|
||||
newName = detachName;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static void MakeDummyMapPatches(int channel, PatchMesh *patch)
|
||||
{
|
||||
patch->setNumMapVerts(channel, 1);
|
||||
patch->tVerts[channel][0] = UVVert(0, 0, 0);
|
||||
patch->setNumMapPatches(channel, patch->numPatches);
|
||||
for (int i = 0; i < patch->numPatches; ++i)
|
||||
{
|
||||
Patch &p = patch->patches[i];
|
||||
TVPatch &tp = patch->tvPatches[channel][i];
|
||||
tp.Init(); // Sets all indices to zero
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Detach all selected patches
|
||||
void EditPatchMod::DoPatchDetach(int copy, int reorient)
|
||||
{
|
||||
int dialoged = 0;
|
||||
TSTR newName(GetString(IDS_TH_PATCH));
|
||||
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();
|
||||
|
||||
// Create a patch mesh object
|
||||
RPO *patchOb = new RPO;
|
||||
patchOb->rpatch = new RPatchMesh;
|
||||
PatchMesh &pmesh = patchOb->patch;
|
||||
RPatchMesh &prmesh = *patchOb->rpatch;
|
||||
int verts = 0;
|
||||
int vecs = 0;
|
||||
int patches = 0;
|
||||
|
||||
int multipleObjects =(mcList.Count() > 1) ? 1 : 0;
|
||||
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 patches selected, we'll need to process this one
|
||||
if (patch->patchSel.NumberSet())
|
||||
{
|
||||
if (!dialoged)
|
||||
{
|
||||
dialoged = 1;
|
||||
if (!GetDetachOptions(ip, newName))
|
||||
goto bail_out;
|
||||
}
|
||||
// Save the unmodified info.
|
||||
if (theHold.Holding())
|
||||
{
|
||||
theHold.Put(new PatchRestore(patchData, this, patch, rpatch, "DoPatchDetach"));
|
||||
}
|
||||
PatchMesh wpatch = *patch;
|
||||
RPatchMesh wrpatch = *rpatch;
|
||||
BitArray vdel(wpatch.numVerts);
|
||||
vdel.ClearAll();
|
||||
BitArray pdel = wpatch.patchSel; // Get inverse selection set
|
||||
// If not copying, delete the patches from this object
|
||||
if (!copy)
|
||||
DeletePatchParts(patch, rpatch, vdel, pdel);
|
||||
pdel = ~wpatch.patchSel; // Get inverse selection set
|
||||
if (pdel.NumberSet())
|
||||
{
|
||||
vdel.ClearAll();
|
||||
DeletePatchParts(&wpatch, &wrpatch, vdel, pdel);
|
||||
}
|
||||
|
||||
// RPatchMesh validity
|
||||
wrpatch.Validity (wpatch, true);
|
||||
|
||||
// We've deleted everything that wasn't selected -- Now add this to the patch object accumulator
|
||||
int oldVerts = pmesh.numVerts;
|
||||
int oldVecs = pmesh.numVecs;
|
||||
int oldPatches = pmesh.numPatches;
|
||||
int newVerts = oldVerts + wpatch.numVerts;
|
||||
int newVecs = oldVecs + wpatch.numVecs;
|
||||
int newPatches = oldPatches + wpatch.numPatches;
|
||||
pmesh.setNumVerts(newVerts, TRUE);
|
||||
pmesh.setNumVecs(newVecs, TRUE);
|
||||
pmesh.setNumPatches(newPatches, TRUE);
|
||||
prmesh.SetNumVerts (newVerts);
|
||||
prmesh.SetNumPatches (newPatches);
|
||||
altered = holdNeeded = 1;
|
||||
Matrix3 tm(1);
|
||||
if (multipleObjects && !reorient)
|
||||
tm = nodes[i]->GetObjectTM(t);
|
||||
int i, i2;
|
||||
for (i = 0, i2 = oldVerts; i < wpatch.numVerts; ++i, ++i2)
|
||||
{
|
||||
pmesh.verts[i2] = wpatch.verts[i];
|
||||
pmesh.verts[i2].p = pmesh.verts[i2].p * tm;
|
||||
|
||||
// Copy rpatch info
|
||||
prmesh.getUIVertex (i2)=wrpatch.getUIVertex (i);
|
||||
}
|
||||
for (i = 0, i2 = oldVecs; i < wpatch.numVecs; ++i, ++i2)
|
||||
{
|
||||
pmesh.vecs[i2] = wpatch.vecs[i];
|
||||
pmesh.vecs[i2].p = pmesh.vecs[i2].p * tm;
|
||||
}
|
||||
for (i = 0, i2 = oldPatches; i < wpatch.numPatches; ++i, ++i2)
|
||||
{
|
||||
Patch &p = wpatch.patches[i];
|
||||
Patch &p2 = pmesh.patches[i2];
|
||||
p2 = p;
|
||||
int j;
|
||||
for (j = 0; j < p2.type; ++j)
|
||||
{
|
||||
// Adjust vertices and interior vectors
|
||||
p2.v[j] += oldVerts;
|
||||
p2.interior[j] += oldVecs;
|
||||
}
|
||||
for (j = 0; j <(p2.type * 2); ++j) // Adjust edge vectors
|
||||
p2.vec[j] += oldVecs;
|
||||
|
||||
// Copy rpatch info
|
||||
prmesh.getUIPatch (i2)=wrpatch.getUIPatch (i);
|
||||
}
|
||||
// Now copy over mapping information
|
||||
int dmaps = pmesh.getNumMaps();
|
||||
int smaps = wpatch.getNumMaps();
|
||||
int maxMaps = dmaps > smaps ? dmaps : smaps;
|
||||
if (maxMaps != dmaps)
|
||||
pmesh.setNumMaps(maxMaps, TRUE);
|
||||
if (maxMaps != smaps)
|
||||
wpatch.setNumMaps(maxMaps, TRUE);
|
||||
// Then make sure any active maps are active in both:
|
||||
int chan;
|
||||
for (chan = 0; chan < maxMaps; ++chan)
|
||||
{
|
||||
if (pmesh.tvPatches[chan] || wpatch.tvPatches[chan])
|
||||
{
|
||||
if (!pmesh.tvPatches[chan])
|
||||
MakeDummyMapPatches(chan, &pmesh);
|
||||
if (!wpatch.tvPatches[chan])
|
||||
MakeDummyMapPatches(chan, &wpatch);
|
||||
}
|
||||
}
|
||||
for (chan = 0; chan < pmesh.getNumMaps(); ++chan)
|
||||
{
|
||||
if (chan < wpatch.getNumMaps())
|
||||
{
|
||||
int oldTVerts = pmesh.numTVerts[chan];
|
||||
int newTVerts = oldTVerts + wpatch.numTVerts[chan];
|
||||
pmesh.setNumMapVerts(chan, newTVerts, TRUE);
|
||||
for (i = 0, i2 = oldTVerts; i < wpatch.numTVerts[chan]; ++i, ++i2)
|
||||
pmesh.tVerts[chan][i2] = wpatch.tVerts[chan][i];
|
||||
if (pmesh.tvPatches[chan])
|
||||
{
|
||||
for (i = 0, i2 = oldPatches; i < wpatch.numPatches; ++i, ++i2)
|
||||
{
|
||||
Patch &p = wpatch.patches[i];
|
||||
TVPatch &tp = wpatch.tvPatches[chan][i];
|
||||
TVPatch &tp2 = pmesh.tvPatches[chan][i2];
|
||||
tp2 = tp;
|
||||
for (int j = 0; j < p.type; ++j) // Adjust vertices
|
||||
tp2.tv[j] += oldTVerts;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
patchData->UpdateChanges(patch, rpatch);
|
||||
patchData->TempData(this)->Invalidate(PART_TOPO);
|
||||
}
|
||||
|
||||
bail_out:
|
||||
patchData->SetFlag(EPD_BEENDONE, TRUE);
|
||||
}
|
||||
|
||||
if (holdNeeded)
|
||||
{
|
||||
pmesh.computeInteriors();
|
||||
pmesh.buildLinkages();
|
||||
INode *newNode = ip->CreateObjectNode(patchOb);
|
||||
newNode->SetMtl(nodes[0]->GetMtl());
|
||||
newNode->SetName(newName.data());
|
||||
patchOb->patch.InvalidateGeomCache();
|
||||
if (!multipleObjects)
|
||||
{
|
||||
// Single input object?
|
||||
if (!reorient)
|
||||
{
|
||||
Matrix3 tm = nodes[0]->GetObjectTM(t);
|
||||
newNode->SetNodeTM(t, tm); // Use this object's TM.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!reorient)
|
||||
{
|
||||
Matrix3 matrix;
|
||||
matrix.IdentityMatrix();
|
||||
newNode->SetNodeTM(t, matrix); // Use identity TM
|
||||
}
|
||||
}
|
||||
newNode->FlagForeground(t); // WORKAROUND!
|
||||
ResolveTopoChanges();
|
||||
theHold.Accept(GetString(IDS_TH_DETACHPATCH));
|
||||
}
|
||||
else
|
||||
{
|
||||
delete patchOb; // Didn't need it after all!
|
||||
if (!dialoged)
|
||||
ip->DisplayTempPrompt(GetString(IDS_TH_NOPATCHESSEL), PROMPT_TIME);
|
||||
theHold.End();
|
||||
}
|
||||
|
||||
nodes.DisposeTemporary();
|
||||
ClearPatchDataFlag(mcList, EPD_BEENDONE);
|
||||
NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
|
||||
ip->RedrawViews(t, REDRAW_NORMAL);
|
||||
}
|
@ -1,341 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
#define PROMPT_TIME 2000
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
int EPM_ExtrudeMouseProc::proc(HWND hwnd, int msg, int point, int flags, IPoint2 m)
|
||||
{
|
||||
ViewExp *vpt = ip->GetViewport(hwnd);
|
||||
Point3 p0, p1;
|
||||
ISpinnerControl *spin;
|
||||
BOOL ln;
|
||||
IPoint2 m2;
|
||||
float amount;
|
||||
switch (msg)
|
||||
{
|
||||
case MOUSE_PROPCLICK:
|
||||
ip->SetStdCommandMode(CID_OBJMOVE);
|
||||
break;
|
||||
|
||||
case MOUSE_POINT:
|
||||
if (!point)
|
||||
{
|
||||
po->BeginExtrude(ip->GetTime());
|
||||
om = m;
|
||||
} else
|
||||
{
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_END);
|
||||
po->EndExtrude(ip->GetTime(), TRUE);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case MOUSE_MOVE:
|
||||
p0 = vpt->MapScreenToView(om, float(-200));
|
||||
// sca 1999.02.24: Find m's projection in om's vertical axis:
|
||||
m2.x = om.x;
|
||||
m2.y = m.y;
|
||||
p1 = vpt->MapScreenToView(m2, float(-200));
|
||||
amount = Length(p1 - p0);
|
||||
if (m.y > om.y)
|
||||
amount *= -1.0f;
|
||||
|
||||
ln = IsDlgButtonChecked(po->hOpsPanel, IDC_EM_EXTYPE_B);
|
||||
po->Extrude(ip->GetTime(), amount, ln);
|
||||
|
||||
spin = GetISpinner(GetDlgItem(po->hOpsPanel, IDC_EP_EXTRUDESPINNER));
|
||||
if (spin)
|
||||
{
|
||||
spin->SetValue(amount, FALSE); // sca - use signed value here too.
|
||||
ReleaseISpinner(spin);
|
||||
}
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_INTERACTIVE);
|
||||
break;
|
||||
|
||||
case MOUSE_ABORT:
|
||||
po->EndExtrude(ip->GetTime(), FALSE);
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_END);
|
||||
break;
|
||||
}
|
||||
|
||||
if (vpt)
|
||||
ip->ReleaseViewport(vpt);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
HCURSOR EPM_ExtrudeSelectionProcessor::GetTransformCursor()
|
||||
{
|
||||
static HCURSOR hCur = NULL;
|
||||
if (!hCur)
|
||||
hCur = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_EXTRUDECUR));
|
||||
return hCur;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
void EPM_ExtrudeCMode::EnterMode()
|
||||
{
|
||||
if (!po->hOpsPanel)
|
||||
return;
|
||||
ICustButton *but = GetICustButton(GetDlgItem(po->hOpsPanel, IDC_EP_EXTRUDE));
|
||||
but->SetCheck(TRUE);
|
||||
ReleaseICustButton(but);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
void EPM_ExtrudeCMode::ExitMode()
|
||||
{
|
||||
if (!po->hOpsPanel)
|
||||
return;
|
||||
ICustButton *but = GetICustButton(GetDlgItem(po->hOpsPanel, IDC_EP_EXTRUDE));
|
||||
but->SetCheck(FALSE);
|
||||
ReleaseICustButton(but);
|
||||
ISpinnerControl *spin;
|
||||
spin = GetISpinner(GetDlgItem(po->hOpsPanel, IDC_EP_EXTRUDESPINNER));
|
||||
if (spin)
|
||||
{
|
||||
spin->SetValue(0.0f, FALSE);
|
||||
ReleaseISpinner(spin);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::DoExtrude()
|
||||
{
|
||||
|
||||
|
||||
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->patchSel.NumberSet())
|
||||
{
|
||||
|
||||
altered = holdNeeded = TRUE;
|
||||
if (theHold.Holding())
|
||||
theHold.Put(new PatchRestore(patchData, this, patch, rpatch));
|
||||
// Call the vertex type change function
|
||||
patch->CreateExtrusion();
|
||||
rpatch->CreateExtrusion(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);
|
||||
|
||||
/*
|
||||
theHold.Begin();
|
||||
patch.RecordTopologyTags();
|
||||
POPatchGenRecord *rec = new POPatchGenRecord(this);
|
||||
if (theHold.Holding())
|
||||
theHold.Put(new PatchObjectRestore(this, rec));
|
||||
|
||||
patch.CreateExtrusion();
|
||||
|
||||
ResolveTopoChanges();
|
||||
theHold.Accept(GetResString(IDS_TH_PATCHADD));
|
||||
|
||||
patch.InvalidateGeomCache();
|
||||
InvalidateMesh();
|
||||
|
||||
NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void EditPatchMod::BeginExtrude(TimeValue t)
|
||||
{
|
||||
if (inExtrude)
|
||||
return;
|
||||
inExtrude = TRUE;
|
||||
theHold.SuperBegin();
|
||||
DoExtrude();
|
||||
// PlugControllersSel(t,sel);
|
||||
theHold.Begin();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::EndExtrude(TimeValue t, BOOL accept)
|
||||
{
|
||||
if (!ip)
|
||||
return;
|
||||
|
||||
if (!inExtrude)
|
||||
return;
|
||||
|
||||
ISpinnerControl *spin;
|
||||
inExtrude = FALSE;
|
||||
spin = GetISpinner(GetDlgItem(hOpsPanel, IDC_EP_EXTRUDESPINNER));
|
||||
if (spin)
|
||||
{
|
||||
spin->SetValue(0, FALSE);
|
||||
ReleaseISpinner(spin);
|
||||
}
|
||||
// TempData()->freeBevelInfo();
|
||||
|
||||
theHold.Accept(GetString(IDS_RB_EXTRUDE));
|
||||
if (accept)
|
||||
theHold.SuperAccept(GetString(IDS_RB_EXTRUDE));
|
||||
else theHold.SuperCancel();
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::Extrude(TimeValue t, float amount, BOOL useLocalNorms)
|
||||
{
|
||||
if (!inExtrude)
|
||||
return;
|
||||
|
||||
|
||||
ModContextList mcList;
|
||||
INodeTab nodes;
|
||||
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->patchSel.NumberSet())
|
||||
{
|
||||
|
||||
altered = holdNeeded = TRUE;
|
||||
if (theHold.Holding())
|
||||
theHold.Put(new PatchRestore(patchData, this, patch, rpatch));
|
||||
|
||||
// Call the vertex type change function
|
||||
#if (MAX_RELEASE < 4000)
|
||||
patch->MoveNormal(amount, useLocalNorms);
|
||||
#else
|
||||
patch->MoveNormal(amount, useLocalNorms, PATCH_PATCH);
|
||||
#endif
|
||||
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);
|
||||
|
||||
/* theHold.Restore();
|
||||
patch.MoveNormal(amount, useLocalNorms);
|
||||
|
||||
patch.InvalidateGeomCache();
|
||||
InvalidateMesh();
|
||||
|
||||
NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -1,326 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
#define PROMPT_TIME 2000
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define OLD_SEL_LEVEL_CHUNK 0x1000 // Original backwards ordering
|
||||
#define SEL_LEVEL_CHUNK 0x1001
|
||||
#define DISP_LATTICE_CHUNK 0x1010
|
||||
#define DISP_SURFACE_CHUNK 0x1020
|
||||
#define DISP_VERTS_CHUNK 0x1030
|
||||
#define EPM_MESH_ATTRIB_CHUNK 0x1040
|
||||
#define EPM_VTESS_ATTRIB_CHUNK 0x1090
|
||||
#define EPM_PTESS_ATTRIB_CHUNK 0x10a0
|
||||
#define EPM_DTESS_ATTRIB_CHUNK 0x10b0
|
||||
#define EPM_NORMAL_TESS_ATTRIB_CHUNK 0x10c0
|
||||
#define EPM_WELD_TESS_ATTRIB_CHUNK 0x10d0
|
||||
#define EPM_RENDERSTEPS_CHUNK 0x10e0
|
||||
#define EPM_SHOWINTERIOR_CHUNK 0x10f0
|
||||
// The following chunk is written on r3 and later files
|
||||
// If not present, named selection data structures need fixup
|
||||
#define EPM_SEL_NAMES_OK 0x1100
|
||||
|
||||
// Names of named selection sets
|
||||
#define NAMEDVSEL_NAMES_CHUNK 0x1050
|
||||
#define NAMEDESEL_NAMES_CHUNK 0x1060
|
||||
#define NAMEDPSEL_NAMES_CHUNK 0x1070
|
||||
#define NAMEDSEL_STRING_CHUNK 0x1080
|
||||
|
||||
#define RPO_MODE_TILE 0x2000
|
||||
#define RPO_MODE_TILE_TRANSITION 0x2001
|
||||
#define RPO_INCLUDE_MESHES 0x2002
|
||||
|
||||
static int namedSelID[] =
|
||||
{
|
||||
NAMEDVSEL_NAMES_CHUNK,
|
||||
NAMEDESEL_NAMES_CHUNK,
|
||||
NAMEDPSEL_NAMES_CHUNK
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
IOResult EditPatchMod::Save(ISave *isave)
|
||||
{
|
||||
Modifier::Save(isave);
|
||||
Interval valid;
|
||||
ULONG nb;
|
||||
// In r3 and later, if the named sel names are OK, write this chunk
|
||||
if (!namedSelNeedsFixup)
|
||||
{
|
||||
isave->BeginChunk(EPM_SEL_NAMES_OK);
|
||||
isave->EndChunk();
|
||||
}
|
||||
isave->BeginChunk(SEL_LEVEL_CHUNK);
|
||||
isave->Write(&selLevel, sizeof(int), &nb);
|
||||
isave-> EndChunk();
|
||||
isave->BeginChunk(DISP_LATTICE_CHUNK);
|
||||
isave->Write(&displayLattice, sizeof(BOOL), &nb);
|
||||
isave-> EndChunk();
|
||||
isave->BeginChunk(DISP_SURFACE_CHUNK);
|
||||
isave->Write(&displaySurface, sizeof(BOOL), &nb);
|
||||
isave-> EndChunk();
|
||||
isave->BeginChunk(EPM_MESH_ATTRIB_CHUNK);
|
||||
isave->Write(&meshSteps, sizeof(int), &nb);
|
||||
// Future use (Not used now)
|
||||
BOOL fakeAdaptive = FALSE;
|
||||
isave->Write(&fakeAdaptive, sizeof(BOOL), &nb);
|
||||
// isave->Write(&meshAdaptive,sizeof(BOOL),&nb); // Future use (Not used now)
|
||||
isave-> EndChunk();
|
||||
|
||||
// 3-18-99 to suport render steps and removal of the mental tesselator
|
||||
isave->BeginChunk(EPM_RENDERSTEPS_CHUNK);
|
||||
if ((meshStepsRender < 0) ||(meshStepsRender > 100))
|
||||
{
|
||||
meshStepsRender = 5;
|
||||
nlassert(0);
|
||||
}
|
||||
isave->Write(&meshStepsRender, sizeof(int), &nb);
|
||||
isave-> EndChunk();
|
||||
isave->BeginChunk(EPM_SHOWINTERIOR_CHUNK);
|
||||
isave->Write(&showInterior, sizeof(BOOL), &nb);
|
||||
isave-> EndChunk();
|
||||
|
||||
isave->BeginChunk(EPM_VTESS_ATTRIB_CHUNK);
|
||||
viewTess.Save(isave);
|
||||
isave-> EndChunk();
|
||||
isave->BeginChunk(EPM_PTESS_ATTRIB_CHUNK);
|
||||
prodTess.Save(isave);
|
||||
isave-> EndChunk();
|
||||
isave->BeginChunk(EPM_DTESS_ATTRIB_CHUNK);
|
||||
dispTess.Save(isave);
|
||||
isave-> EndChunk();
|
||||
|
||||
// Tile mode
|
||||
isave->BeginChunk(RPO_MODE_TILE);
|
||||
isave->Write(&tileMode, sizeof(tileMode), &nb);
|
||||
isave->Write(&tileLevel, sizeof(tileLevel), &nb);
|
||||
isave->Write(&keepMapping, sizeof(keepMapping), &nb);
|
||||
isave-> EndChunk();
|
||||
|
||||
// Tile mode
|
||||
isave->BeginChunk(RPO_INCLUDE_MESHES);
|
||||
isave->Write(&includeMeshes, sizeof(includeMeshes), &nb);
|
||||
isave-> EndChunk();
|
||||
|
||||
// Tile mode
|
||||
isave->BeginChunk(RPO_MODE_TILE_TRANSITION);
|
||||
isave->Write(&transitionType, sizeof(transitionType), &nb);
|
||||
isave-> EndChunk();
|
||||
|
||||
isave->BeginChunk(EPM_NORMAL_TESS_ATTRIB_CHUNK);
|
||||
isave->Write(&mViewTessNormals, sizeof(BOOL), &nb);
|
||||
isave->Write(&mProdTessNormals, sizeof(BOOL), &nb);
|
||||
isave-> EndChunk();
|
||||
isave->BeginChunk(EPM_WELD_TESS_ATTRIB_CHUNK);
|
||||
isave->Write(&mViewTessWeld, sizeof(BOOL), &nb);
|
||||
isave->Write(&mProdTessWeld, sizeof(BOOL), &nb);
|
||||
isave-> EndChunk();
|
||||
|
||||
// Save names of named selection sets
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
if (namedSel[j].Count())
|
||||
{
|
||||
isave->BeginChunk(namedSelID[j]);
|
||||
for (int i = 0; i < namedSel[j].Count(); i++)
|
||||
{
|
||||
isave->BeginChunk(NAMEDSEL_STRING_CHUNK);
|
||||
isave->WriteWString(*namedSel[j][i]);
|
||||
isave->EndChunk();
|
||||
}
|
||||
isave->EndChunk();
|
||||
}
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
IOResult EditPatchMod::LoadNamedSelChunk(ILoad *iload, int level)
|
||||
{
|
||||
IOResult res;
|
||||
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case NAMEDSEL_STRING_CHUNK:
|
||||
{
|
||||
TCHAR *name;
|
||||
res = iload->ReadWStringChunk(&name);
|
||||
// Set the name in the modifier
|
||||
AddSet(TSTR(name), level + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
IOResult EditPatchMod::Load(ILoad *iload)
|
||||
{
|
||||
Modifier::Load(iload);
|
||||
IOResult res;
|
||||
ULONG nb;
|
||||
namedSelNeedsFixup = TRUE; // Pre-r3 default
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case EPM_SEL_NAMES_OK:
|
||||
namedSelNeedsFixup = FALSE;
|
||||
break;
|
||||
case NAMEDVSEL_NAMES_CHUNK:
|
||||
{
|
||||
res = LoadNamedSelChunk(iload, 0);
|
||||
break;
|
||||
}
|
||||
case NAMEDESEL_NAMES_CHUNK:
|
||||
{
|
||||
res = LoadNamedSelChunk(iload, 1);
|
||||
break;
|
||||
}
|
||||
case NAMEDPSEL_NAMES_CHUNK:
|
||||
{
|
||||
res = LoadNamedSelChunk(iload, 2);
|
||||
break;
|
||||
}
|
||||
|
||||
case OLD_SEL_LEVEL_CHUNK: // Correct backwards ordering
|
||||
{
|
||||
short sl;
|
||||
res = iload->Read(&sl, sizeof(short), &nb);
|
||||
selLevel = sl;
|
||||
switch (selLevel)
|
||||
{
|
||||
case 1:
|
||||
selLevel = EP_PATCH;
|
||||
break;
|
||||
case 3:
|
||||
selLevel = EP_VERTEX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SEL_LEVEL_CHUNK:
|
||||
res = iload->Read(&selLevel, sizeof(int), &nb);
|
||||
break;
|
||||
case DISP_LATTICE_CHUNK:
|
||||
res = iload->Read(&displayLattice, sizeof(BOOL), &nb);
|
||||
break;
|
||||
case DISP_SURFACE_CHUNK:
|
||||
res = iload->Read(&displaySurface, sizeof(BOOL), &nb);
|
||||
break;
|
||||
case DISP_VERTS_CHUNK:
|
||||
iload->SetObsolete();
|
||||
break;
|
||||
case EPM_MESH_ATTRIB_CHUNK:
|
||||
res = iload->Read(&meshSteps, sizeof(int), &nb);
|
||||
res = iload->Read(&meshAdaptive, sizeof(BOOL), &nb);
|
||||
break;
|
||||
// 3-18-99 to suport render steps and removal of the mental tesselator
|
||||
case EPM_RENDERSTEPS_CHUNK:
|
||||
res = iload->Read(&meshStepsRender, sizeof(int), &nb);
|
||||
if ((meshStepsRender < 0) ||(meshStepsRender > 100))
|
||||
{
|
||||
meshStepsRender = 5;
|
||||
nlassert(0);
|
||||
}
|
||||
break;
|
||||
case EPM_SHOWINTERIOR_CHUNK:
|
||||
res = iload->Read(&showInterior, sizeof(BOOL), &nb);
|
||||
break;
|
||||
|
||||
case EPM_VTESS_ATTRIB_CHUNK:
|
||||
viewTess.Load(iload);
|
||||
break;
|
||||
case EPM_PTESS_ATTRIB_CHUNK:
|
||||
prodTess.Load(iload);
|
||||
break;
|
||||
case EPM_DTESS_ATTRIB_CHUNK:
|
||||
dispTess.Load(iload);
|
||||
break;
|
||||
case EPM_NORMAL_TESS_ATTRIB_CHUNK:
|
||||
res = iload->Read(&mViewTessNormals, sizeof(BOOL), &nb);
|
||||
res = iload->Read(&mProdTessNormals, sizeof(BOOL), &nb);
|
||||
break;
|
||||
case EPM_WELD_TESS_ATTRIB_CHUNK:
|
||||
res = iload->Read(&mViewTessWeld, sizeof(BOOL), &nb);
|
||||
res = iload->Read(&mProdTessWeld, sizeof(BOOL), &nb);
|
||||
break;
|
||||
|
||||
case RPO_MODE_TILE:
|
||||
res = iload->Read(&tileMode, sizeof(tileMode), &nb);
|
||||
res = iload->Read(&tileLevel, sizeof(tileLevel), &nb);
|
||||
res = iload->Read(&keepMapping, sizeof(keepMapping), &nb);
|
||||
break;
|
||||
|
||||
case RPO_INCLUDE_MESHES:
|
||||
res = iload->Read(&includeMeshes, sizeof(includeMeshes), &nb);
|
||||
break;
|
||||
|
||||
case RPO_MODE_TILE_TRANSITION:
|
||||
res = iload->Read(&transitionType, sizeof(transitionType), &nb);
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define EDITPATCHDATA_CHUNK 0x1000
|
||||
|
||||
IOResult EditPatchMod::SaveLocalData(ISave *isave, LocalModData *ld)
|
||||
{
|
||||
EditPatchData *ep =(EditPatchData *)ld;
|
||||
|
||||
isave->BeginChunk(EDITPATCHDATA_CHUNK);
|
||||
ep->Save(isave);
|
||||
isave->EndChunk();
|
||||
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
IOResult EditPatchMod::LoadLocalData(ILoad *iload, LocalModData **pld)
|
||||
{
|
||||
IOResult res;
|
||||
EditPatchData *ep;
|
||||
if (*pld == NULL)
|
||||
{
|
||||
*pld =(LocalModData *) new EditPatchData(this);
|
||||
}
|
||||
ep =(EditPatchData *)*pld;
|
||||
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case EDITPATCHDATA_CHUNK:
|
||||
res = ep->Load(iload);
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
@ -1,161 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
#define PROMPT_TIME 2000
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
extern HIMAGELIST hFaceImages;
|
||||
int patchHitOverride = 0; // If zero, no override is done
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
class EPImageListDestroyer
|
||||
{
|
||||
~EPImageListDestroyer()
|
||||
{
|
||||
if (hFaceImages)
|
||||
ImageList_Destroy(hFaceImages);
|
||||
}
|
||||
};
|
||||
|
||||
PatchRightMenu pMenu;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void LoadImages()
|
||||
{
|
||||
if (hFaceImages)
|
||||
return;
|
||||
|
||||
HBITMAP hBitmap, hMask;
|
||||
hFaceImages = ImageList_Create(24, 23, ILC_COLOR | ILC_MASK, 6, 0);
|
||||
hBitmap = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_PATCHSELTYPES));
|
||||
hMask = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_PATCHSELMASK));
|
||||
ImageList_Add(hFaceImages, hBitmap, hMask);
|
||||
DeleteObject(hBitmap);
|
||||
DeleteObject(hMask);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void PatchRightMenu::Init(RightClickMenuManager* manager, HWND hWnd, IPoint2 m)
|
||||
{
|
||||
switch (ep->GetSubobjectLevel())
|
||||
{
|
||||
case EP_VERTEX:
|
||||
if (ep->RememberVertThere(hWnd, m))
|
||||
{
|
||||
int oldType = -1;
|
||||
int flags1, flags2;
|
||||
flags1 = flags2 = MF_STRING;
|
||||
switch (ep->rememberedData)
|
||||
{
|
||||
case PVERT_COPLANAR:
|
||||
flags1 |= MF_CHECKED;
|
||||
break;
|
||||
case 0:
|
||||
flags2 |= MF_CHECKED;
|
||||
break;
|
||||
}
|
||||
manager->AddMenu(this, MF_SEPARATOR, 0, NULL);
|
||||
manager->AddMenu(this, flags1, PVERT_COPLANAR, GetString(IDS_TH_COPLANAR));
|
||||
manager->AddMenu(this, flags2, 0, GetString(IDS_TH_CORNER));
|
||||
}
|
||||
break;
|
||||
case EP_PATCH:
|
||||
if (ep->RememberPatchThere(hWnd, m))
|
||||
{
|
||||
int oldType = -1;
|
||||
int flags1, flags2;
|
||||
flags1 = flags2 = MF_STRING;
|
||||
switch (ep->rememberedData)
|
||||
{
|
||||
case PATCH_AUTO:
|
||||
flags1 |= MF_CHECKED;
|
||||
break;
|
||||
case 0:
|
||||
flags2 |= MF_CHECKED;
|
||||
break;
|
||||
}
|
||||
manager->AddMenu(this, MF_SEPARATOR, 0, NULL);
|
||||
manager->AddMenu(this, flags1, PATCH_AUTO, GetString(IDS_TH_AUTOINTERIOR));
|
||||
manager->AddMenu(this, flags2, 0, GetString(IDS_TH_MANUALINTERIOR));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void PatchRightMenu::Selected(UINT id)
|
||||
{
|
||||
switch (ep->GetSubobjectLevel())
|
||||
{
|
||||
case EP_VERTEX:
|
||||
ep->SetRememberedVertType((int)id);
|
||||
break;
|
||||
case EP_PATCH:
|
||||
ep->SetRememberedPatchType((int)id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
int EditPatchMod::HitTest(TimeValue t, INode* inode, int type, int crossing,
|
||||
int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc)
|
||||
{
|
||||
Interval valid;
|
||||
int savedLimits, res = 0;
|
||||
GraphicsWindow *gw = vpt->getGW();
|
||||
HitRegion hr;
|
||||
MakeHitRegion(hr, type, crossing, 4, p);
|
||||
gw->setHitRegion(&hr);
|
||||
Matrix3 mat = inode->GetObjectTM(t);
|
||||
gw->setTransform(mat);
|
||||
gw->setRndLimits(((savedLimits = gw->getRndLimits()) | GW_PICK) & ~GW_ILLUM);
|
||||
gw->clearHitCode();
|
||||
|
||||
if (mc->localData)
|
||||
{
|
||||
EditPatchData *patchData =(EditPatchData*)mc->localData;
|
||||
RPatchMesh *rpatch;
|
||||
PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch);
|
||||
if (!patch)
|
||||
return FALSE;
|
||||
|
||||
SubPatchHitList hitList;
|
||||
PatchSubHitRec *rec;
|
||||
|
||||
rpatch->UpdateBinding (*patch, t);
|
||||
|
||||
if (selLevel!=EP_TILE)
|
||||
{
|
||||
res = patch->SubObjectHitTest(gw, gw->getMaterial(), &hr,
|
||||
flags | ((patchHitOverride) ? patchHitLevel[patchHitOverride] : patchHitLevel[selLevel]), hitList);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = rpatch->SubObjectHitTest(gw, gw->getMaterial(), &hr,
|
||||
flags | ((patchHitOverride) ? patchHitLevel[patchHitOverride] : patchHitLevel[selLevel]), hitList,
|
||||
t, *patch);
|
||||
}
|
||||
|
||||
rec = hitList.First();
|
||||
while (rec)
|
||||
{
|
||||
vpt->LogHit(inode, mc, rec->dist, 123456, new PatchHitData(rec->patch, rec->index, rec->type));
|
||||
rec = rec->Next();
|
||||
}
|
||||
}
|
||||
|
||||
gw->setRndLimits(savedLimits);
|
||||
return res;
|
||||
}
|
@ -1,464 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
#define PROMPT_TIME 2000
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// watje unhide all
|
||||
static void UnHidePatches(PatchMesh *patch)
|
||||
{
|
||||
// If positive vertex number, do it to just one vertex
|
||||
int patches = patch->numPatches;
|
||||
int i;
|
||||
for (i = 0; i < patches; i++)
|
||||
{
|
||||
if (patch->patches[i].IsHidden())
|
||||
patch->patches[i].SetHidden(FALSE);
|
||||
}
|
||||
int verts = patch->numVerts;
|
||||
for (i = 0; i < verts; i++)
|
||||
{
|
||||
if (patch->verts[i].IsHidden())
|
||||
patch->verts[i].SetHidden(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
// watje 12-10-98
|
||||
void EditPatchMod::DoUnHide() {
|
||||
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->patchSel.NumberSet()) {
|
||||
if (1)
|
||||
{
|
||||
altered = holdNeeded = TRUE;
|
||||
if (theHold.Holding())
|
||||
theHold.Put(new PatchRestore(patchData, this, patch, rpatch));
|
||||
// Call the vertex type change function
|
||||
UnHidePatches(patch);
|
||||
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);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::DoHide(int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EP_VERTEX:
|
||||
DoVertHide();
|
||||
break;
|
||||
case EP_EDGE:
|
||||
DoEdgeHide();
|
||||
break;
|
||||
case EP_PATCH:
|
||||
DoPatchHide();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// watje
|
||||
static void FixUpVerts(PatchMesh *patch)
|
||||
{
|
||||
int patches = patch->numPatches;
|
||||
for (int i = 0; i < patches; i++)
|
||||
{
|
||||
|
||||
if (!(patch->patches[i].IsHidden()))
|
||||
{
|
||||
int ct = 4;
|
||||
if (patch->patches[i].type == PATCH_TRI)
|
||||
ct = 3;
|
||||
for (int k = 0; k < ct; k++)
|
||||
{
|
||||
int a = patch->patches[i].v[k];
|
||||
patch->verts[a].SetHidden(FALSE);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
// watje hide patch
|
||||
static void HidePatches(PatchMesh *patch)
|
||||
{
|
||||
// If positive vertex number, do it to just one vertex
|
||||
int patches = patch->numPatches;
|
||||
BitArray &psel = patch->patchSel;
|
||||
for (int i = 0; i < patches; i++)
|
||||
{
|
||||
if (psel[i])
|
||||
{
|
||||
patch->patches[i].SetHidden(TRUE);
|
||||
// hide all
|
||||
int ct = 4;
|
||||
if (patch->patches[i].type == PATCH_TRI)
|
||||
ct = 3;
|
||||
for (int k = 0; k < ct; k++)
|
||||
{
|
||||
int a = patch->patches[i].v[k];
|
||||
patch->verts[a].SetHidden(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
FixUpVerts(patch);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::DoPatchHide()
|
||||
{
|
||||
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->patchSel.NumberSet())
|
||||
{
|
||||
altered = holdNeeded = TRUE;
|
||||
if (theHold.Holding())
|
||||
theHold.Put(new PatchRestore(patchData, this, patch, rpatch));
|
||||
// Call the vertex type change function
|
||||
HidePatches(patch);
|
||||
patch->patchSel.ClearAll();
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// watje hide patches by verts
|
||||
static void HideVerts(PatchMesh *patch)
|
||||
{
|
||||
// If positive vertex number, do it to just one vertex
|
||||
int patches = patch->numPatches;
|
||||
BitArray &vsel = patch->vertSel;
|
||||
int i;
|
||||
for (i = 0; i < patches; i++)
|
||||
{
|
||||
int ct = 4;
|
||||
if (patch->patches[i].type == PATCH_TRI)
|
||||
ct = 3;
|
||||
for (int k = 0; k < ct; k++)
|
||||
{
|
||||
int a = patch->patches[i].v[k];
|
||||
|
||||
if (vsel[a])
|
||||
{
|
||||
patch->patches[i].SetHidden(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < patches; i++)
|
||||
{
|
||||
if (patch->patches[i].IsHidden())
|
||||
{
|
||||
// hide all
|
||||
int ct = 4;
|
||||
if (patch->patches[i].type == PATCH_TRI)
|
||||
ct = 3;
|
||||
for (int k = 0; k < ct; k++)
|
||||
{
|
||||
int a = patch->patches[i].v[k];
|
||||
patch->verts[a].SetHidden(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FixUpVerts(patch);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::DoVertHide()
|
||||
{
|
||||
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
|
||||
HideVerts(patch);
|
||||
patch->vertSel.ClearAll();
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// watje hide patches by verts
|
||||
static void HideEdges(PatchMesh *patch)
|
||||
{
|
||||
// If positive vertex number, do it to just one vertex
|
||||
int edges = patch->numEdges;
|
||||
BitArray &esel = patch->edgeSel;
|
||||
int i;
|
||||
for (i = 0; i < edges; i++)
|
||||
{
|
||||
if (esel[i])
|
||||
{
|
||||
#if (MAX_RELEASE < 4000)
|
||||
int a = patch->edges[i].patch1;
|
||||
int b = patch->edges[i].patch2;
|
||||
#else // (MAX_RELEASE < 4000)
|
||||
int a = patch->edges[i].patches[0];
|
||||
int b = patch->edges[i].patches[1];
|
||||
#endif // (MAX_RELEASE < 4000)
|
||||
if (a>0)
|
||||
patch->patches[a].SetHidden(TRUE);
|
||||
if (b>0)
|
||||
patch->patches[b].SetHidden(TRUE);
|
||||
}
|
||||
}
|
||||
int patches = patch->numPatches;
|
||||
for (i = 0; i < patches; i++)
|
||||
{
|
||||
if (patch->patches[i].IsHidden())
|
||||
{
|
||||
// hide all
|
||||
int ct = 4;
|
||||
if (patch->patches[i].type == PATCH_TRI)
|
||||
ct = 3;
|
||||
for (int k = 0; k < ct; k++)
|
||||
{
|
||||
int a = patch->patches[i].v[k];
|
||||
patch->verts[a].SetHidden(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
FixUpVerts(patch);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::DoEdgeHide()
|
||||
{
|
||||
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->edgeSel.NumberSet())
|
||||
{
|
||||
altered = holdNeeded = TRUE;
|
||||
if (theHold.Holding())
|
||||
theHold.Put(new PatchRestore(patchData, this, patch, rpatch));
|
||||
// Call the vertex type change function
|
||||
HideEdges(patch);
|
||||
patch->edgeSel.ClearAll();
|
||||
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);
|
||||
|
||||
}
|
@ -1,203 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
#define PROMPT_TIME 2000
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
@ -1,321 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -1,789 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
#define PROMPT_TIME 2000
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
extern int sbmParams[4];
|
||||
extern DWORD sbsParams[3];
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL CALLBACK SelectByMatDlgProc(
|
||||
HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static int *param;
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
param =(int*)lParam;
|
||||
SetupIntSpinner(hWnd, IDC_MAT_IDSPIN, IDC_MAT_ID, 1, MAX_MATID, param[0]);
|
||||
CheckDlgButton(hWnd, IDC_CLEARSELECTION, param[1]);
|
||||
/*SetupIntSpinner(hWnd, IDC_TESS_U_SPIN, IDC_TESS_U2, 1, RPO_DEFAULT_TESSEL, param[2]);
|
||||
SetupIntSpinner(hWnd, IDC_TESS_V_SPIN, IDC_TESS_V2, 1, RPO_DEFAULT_TESSEL, param[3]);*/
|
||||
CenterWindow(hWnd, GetParent(hWnd));
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDOK:
|
||||
{
|
||||
ISpinnerControl *spin = GetISpinner(GetDlgItem(hWnd, IDC_MAT_IDSPIN));
|
||||
param[0] = spin->GetIVal();
|
||||
param[1] = IsDlgButtonChecked(hWnd, IDC_CLEARSELECTION);
|
||||
ReleaseISpinner(spin);
|
||||
EndDialog(hWnd, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
case IDCANCEL:
|
||||
EndDialog(hWnd, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void SetSmoothButtonState(HWND hWnd, DWORD bits, DWORD invalid, DWORD unused = 0)
|
||||
{
|
||||
for (int i = IDC_SMOOTH_GRP1; i < IDC_SMOOTH_GRP1 + 32; i++)
|
||||
{
|
||||
if ((unused&(1 << (i - IDC_SMOOTH_GRP1))))
|
||||
{
|
||||
ShowWindow(GetDlgItem(hWnd, i), SW_HIDE);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((invalid&(1 << (i - IDC_SMOOTH_GRP1))))
|
||||
{
|
||||
SetWindowText(GetDlgItem(hWnd, i), NULL);
|
||||
SendMessage(GetDlgItem(hWnd, i), CC_COMMAND, CC_CMD_SET_STATE, FALSE);
|
||||
} else
|
||||
{
|
||||
TSTR buf;
|
||||
buf.printf(_T("%d"), i - IDC_SMOOTH_GRP1 + 1);
|
||||
SetWindowText(GetDlgItem(hWnd, i), buf);
|
||||
SendMessage(GetDlgItem(hWnd, i), CC_COMMAND, CC_CMD_SET_STATE,(bits&(1 << (i - IDC_SMOOTH_GRP1)))?TRUE:FALSE);
|
||||
}
|
||||
InvalidateRect(GetDlgItem(hWnd, i), NULL, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL CALLBACK SelectBySmoothDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static DWORD *param;
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
param =(DWORD*)lParam;
|
||||
int i;
|
||||
for (i = IDC_SMOOTH_GRP1; i < IDC_SMOOTH_GRP1 + 32; i++)
|
||||
SendMessage(GetDlgItem(hWnd, i), CC_COMMAND, CC_CMD_SET_TYPE, CBT_CHECK);
|
||||
SetSmoothButtonState(hWnd, param[0], 0, param[2]);
|
||||
CheckDlgButton(hWnd, IDC_CLEARSELECTION, param[1]);
|
||||
CenterWindow(hWnd, GetParent(hWnd));
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
if (LOWORD(wParam) >= IDC_SMOOTH_GRP1 &&
|
||||
LOWORD(wParam) <= IDC_SMOOTH_GRP32)
|
||||
{
|
||||
ICustButton *iBut = GetICustButton(GetDlgItem(hWnd, LOWORD(wParam)));
|
||||
int shift = LOWORD(wParam) - IDC_SMOOTH_GRP1;
|
||||
if (iBut->IsChecked())
|
||||
{
|
||||
param[0] |= 1 << shift;
|
||||
} else
|
||||
{
|
||||
param[0] &= ~(1 << shift);
|
||||
}
|
||||
ReleaseICustButton(iBut);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDOK:
|
||||
param[1] = IsDlgButtonChecked(hWnd, IDC_CLEARSELECTION);
|
||||
EndDialog(hWnd, 1);
|
||||
break;
|
||||
|
||||
case IDCANCEL:
|
||||
EndDialog(hWnd, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL CALLBACK PatchTileDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
EditPatchMod *ep =(EditPatchMod *)GetWindowLong(hDlg, GWL_USERDATA);
|
||||
if (!ep && message != WM_INITDIALOG)
|
||||
return FALSE;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
|
||||
ep =(EditPatchMod *)lParam;
|
||||
ep->hTilePanel = hDlg;
|
||||
SetWindowLong(hDlg, GWL_USERDATA, (LONG)ep);
|
||||
ep->tileNum = SetupIntSpinner(hDlg, IDC_TILE_MAT_SPIN, IDC_TILE_MAT, 0, 65535, 0);
|
||||
ep->tileRot = SetupIntSpinner(hDlg, IDC_TILE_ROT_SPIN, IDC_TILE_ROT, 0, 3, 0);
|
||||
ep->SetTileDlgEnables();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_DESTROY:
|
||||
if (ep->tileNum)
|
||||
{
|
||||
ReleaseISpinner(ep->tileNum);
|
||||
ep->tileNum = NULL;
|
||||
}
|
||||
if (ep->tileRot)
|
||||
{
|
||||
ReleaseISpinner(ep->tileRot);
|
||||
ep->tileRot = NULL;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case CC_SPINNER_CHANGE:
|
||||
/*switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_TILE_MAT_SPIN:
|
||||
if (HIWORD(wParam))
|
||||
break; // No interactive action
|
||||
ep->SetTileNum (ep->tileNum->GetIVal());
|
||||
break;
|
||||
case IDC_TILE_ROT_SPIN:
|
||||
if (HIWORD(wParam))
|
||||
break; // No interactive action
|
||||
ep->SetTileRot (ep->tileRot->GetIVal());
|
||||
break;
|
||||
}*/
|
||||
break;
|
||||
|
||||
case CC_SPINNER_BUTTONUP:
|
||||
/*switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_TILE_MAT_SPIN:
|
||||
ep->SetTileNum (ep->tileNum->GetIVal());
|
||||
ep->ip->RedrawViews(ep->ip->GetTime(), REDRAW_END);
|
||||
break;
|
||||
case IDC_TILE_ROT_SPIN:
|
||||
ep->SetTileRot (ep->tileRot->GetIVal());
|
||||
ep->ip->RedrawViews(ep->ip->GetTime(), REDRAW_END);
|
||||
break;
|
||||
}*/
|
||||
break;
|
||||
|
||||
case WM_PAINT:
|
||||
if (!ep->tileUIValid)
|
||||
{
|
||||
// Tilenum
|
||||
/*ULONG u = ep->GetTileNum();
|
||||
if (u == 0xffffffff)
|
||||
{
|
||||
ep->tileNum->SetIndeterminate(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ep->tileNum->SetIndeterminate(FALSE);
|
||||
ep->tileNum->SetValue((int)u, FALSE);
|
||||
}
|
||||
|
||||
// Tilerot
|
||||
int v = ep->GetTileRot();
|
||||
if (v == -1)
|
||||
{
|
||||
ep->tileRot->SetIndeterminate(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ep->tileRot->SetIndeterminate(FALSE);
|
||||
ep->tileRot->SetValue(v, FALSE);
|
||||
}*/
|
||||
|
||||
ep->patchUIValid = TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_MOUSEMOVE:
|
||||
ep->ip->RollupMouseMessage(hDlg, message, wParam, lParam);
|
||||
return FALSE;
|
||||
|
||||
case WM_COMMAND:
|
||||
/*switch (LOWORD(wParam))
|
||||
{
|
||||
}*/
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL CALLBACK PatchEdgeDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
EditPatchMod *ep =(EditPatchMod *)GetWindowLong(hDlg, GWL_USERDATA);
|
||||
if (!ep && message != WM_INITDIALOG)
|
||||
return FALSE;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
|
||||
ep =(EditPatchMod *)lParam;
|
||||
ep->hEdgePanel = hDlg;
|
||||
SetWindowLong(hDlg, GWL_USERDATA, (LONG)ep);
|
||||
ep->SetEdgeDlgEnables();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_DESTROY:
|
||||
return FALSE;
|
||||
|
||||
case WM_PAINT:
|
||||
if (!ep->edgeUIValid)
|
||||
{
|
||||
// No smooth active ?
|
||||
HWND hButton=GetDlgItem (hDlg, IDC_NO_SMOOTH);
|
||||
nlassert (hButton);
|
||||
if (IsWindowEnabled (hButton))
|
||||
{
|
||||
// Get its value
|
||||
switch (ep->getSmoothFlags ())
|
||||
{
|
||||
case 0:
|
||||
CheckDlgButton (hDlg, IDC_NO_SMOOTH, BST_UNCHECKED);
|
||||
break;
|
||||
case 1:
|
||||
CheckDlgButton (hDlg, IDC_NO_SMOOTH, BST_CHECKED);
|
||||
break;
|
||||
case 2:
|
||||
CheckDlgButton (hDlg, IDC_NO_SMOOTH, BST_INDETERMINATE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Valid now
|
||||
ep->edgeUIValid = TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_MOUSEMOVE:
|
||||
ep->ip->RollupMouseMessage(hDlg, message, wParam, lParam);
|
||||
return FALSE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_NO_SMOOTH:
|
||||
// 3 states management
|
||||
if (IsDlgButtonChecked(hDlg, IDC_NO_SMOOTH)==BST_INDETERMINATE)
|
||||
CheckDlgButton (hDlg, IDC_NO_SMOOTH, BST_UNCHECKED);
|
||||
|
||||
// Set the smooth flag for selected edges if state is checked or indeterminate
|
||||
ep->setSmoothFlags (IsDlgButtonChecked(hDlg, IDC_NO_SMOOTH)==BST_CHECKED);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL CALLBACK PatchSurfDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
EditPatchMod *ep =(EditPatchMod *)GetWindowLong(hDlg, GWL_USERDATA);
|
||||
if (!ep && message != WM_INITDIALOG)
|
||||
return FALSE;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
ep = (EditPatchMod *)lParam;
|
||||
ep->hSurfPanel = hDlg;
|
||||
|
||||
for (int i = IDC_SMOOTH_GRP1; i < IDC_SMOOTH_GRP1 + 32; i++)
|
||||
SendMessage(GetDlgItem(hDlg, i), CC_COMMAND, CC_CMD_SET_TYPE, CBT_CHECK);
|
||||
SetWindowLong(hDlg, GWL_USERDATA, (LONG)ep);
|
||||
ep->matSpin = SetupIntSpinner(hDlg, IDC_MAT_IDSPIN, IDC_MAT_ID, 1, MAX_MATID, 0);
|
||||
ep->tessUSpin = SetupIntSpinner(hDlg, IDC_TESS_U_SPIN, IDC_TESS_U2, 1, 4, RPO_DEFAULT_TESSEL);
|
||||
ep->tessVSpin = SetupIntSpinner(hDlg, IDC_TESS_V_SPIN, IDC_TESS_V2, 1, 4, RPO_DEFAULT_TESSEL);
|
||||
|
||||
ep->SetSurfDlgEnables();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_DESTROY:
|
||||
if (ep->matSpin)
|
||||
{
|
||||
ReleaseISpinner(ep->matSpin);
|
||||
ep->matSpin = NULL;
|
||||
}
|
||||
if (ep->tessUSpin)
|
||||
{
|
||||
ReleaseISpinner(ep->tessUSpin);
|
||||
ep->tessUSpin = NULL;
|
||||
}
|
||||
if (ep->tessVSpin)
|
||||
{
|
||||
ReleaseISpinner(ep->tessVSpin);
|
||||
ep->tessVSpin = NULL;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case CC_SPINNER_CHANGE:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_MAT_IDSPIN:
|
||||
if (HIWORD(wParam))
|
||||
break; // No interactive action
|
||||
ep->SetSelMatIndex(ep->matSpin->GetIVal() - 1);
|
||||
break;
|
||||
case IDC_TESS_U_SPIN:
|
||||
case IDC_TESS_V_SPIN:
|
||||
if (HIWORD(wParam))
|
||||
break; // No interactive action
|
||||
ep->SetSelTess(ep->tessUSpin->GetIVal(), ep->tessVSpin->GetIVal());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case CC_SPINNER_BUTTONUP:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_MAT_IDSPIN:
|
||||
ep->SetSelMatIndex(ep->matSpin->GetIVal() - 1);
|
||||
ep->ip->RedrawViews(ep->ip->GetTime(), REDRAW_END);
|
||||
break;
|
||||
case IDC_TESS_U_SPIN:
|
||||
case IDC_TESS_V_SPIN:
|
||||
ep->SetSelTess(ep->tessUSpin->GetIVal(), ep->tessVSpin->GetIVal());
|
||||
ep->ip->RedrawViews(ep->ip->GetTime(), REDRAW_END);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_PAINT:
|
||||
if (!ep->patchUIValid)
|
||||
{
|
||||
// Material index
|
||||
int mat = ep->GetSelMatIndex();
|
||||
if (mat == -1)
|
||||
{
|
||||
ep->matSpin->SetIndeterminate(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ep->matSpin->SetIndeterminate(FALSE);
|
||||
ep->matSpin->SetValue(mat + 1, FALSE);
|
||||
}
|
||||
// Smoothing groups
|
||||
DWORD invalid, bits;
|
||||
bits = ep->GetSelSmoothBits(invalid);
|
||||
SetSmoothButtonState(hDlg, bits, invalid);
|
||||
|
||||
// U tess index
|
||||
int u = ep->GetSelTessU();
|
||||
if (u == -1)
|
||||
{
|
||||
ep->tessUSpin->SetIndeterminate(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ep->tessUSpin->SetIndeterminate(FALSE);
|
||||
ep->tessUSpin->SetValue(u, FALSE);
|
||||
}
|
||||
|
||||
// V tess index
|
||||
int v = ep->GetSelTessV();
|
||||
if (v == -1)
|
||||
{
|
||||
ep->tessVSpin->SetIndeterminate(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ep->tessVSpin->SetIndeterminate(FALSE);
|
||||
ep->tessVSpin->SetValue(v, FALSE);
|
||||
}
|
||||
|
||||
ep->patchUIValid = TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_MOUSEMOVE:
|
||||
ep->ip->RollupMouseMessage(hDlg, message, wParam, lParam);
|
||||
return FALSE;
|
||||
|
||||
case WM_COMMAND:
|
||||
if (LOWORD(wParam) >= IDC_SMOOTH_GRP1 &&
|
||||
LOWORD(wParam) <= IDC_SMOOTH_GRP32)
|
||||
{
|
||||
ICustButton *iBut = GetICustButton(GetDlgItem(hDlg, LOWORD(wParam)));
|
||||
int bit = iBut->IsChecked() ? 1 : 0;
|
||||
int shift = LOWORD(wParam) - IDC_SMOOTH_GRP1;
|
||||
ep->SetSelSmoothBits(bit << shift, 1 << shift);
|
||||
ReleaseICustButton(iBut);
|
||||
break;
|
||||
}
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
// Material
|
||||
case IDC_SELECT_BYID:
|
||||
{
|
||||
if (DialogBoxParam(
|
||||
hInstance,
|
||||
MAKEINTRESOURCE(IDD_SELECTBYMAT),
|
||||
ep->ip->GetMAXHWnd(),
|
||||
SelectByMatDlgProc,
|
||||
(LPARAM)sbmParams))
|
||||
{
|
||||
|
||||
ep->SelectByMat(sbmParams[0] - 1/*index*/, sbmParams[1]/*clear*/);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Smoothing groups
|
||||
case IDC_SELECTBYSMOOTH:
|
||||
{
|
||||
sbsParams[2] = ~ep->GetUsedSmoothBits();
|
||||
if (DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_EM_SELECTBYSMOOTH),
|
||||
ep->ip->GetMAXHWnd(), SelectBySmoothDlgProc, (LPARAM)sbsParams))
|
||||
{
|
||||
ep->SelectBySmoothGroup(sbsParams[0], (BOOL)sbsParams[1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IDC_SMOOTH_CLEAR:
|
||||
ep->SetSelSmoothBits(0, 0xffffffff);
|
||||
break;
|
||||
// Balance button
|
||||
case IDC_BALANCE_SELECTED:
|
||||
{
|
||||
ep->BalanceSelPatch ();
|
||||
ep->ip->RedrawViews(ep->ip->GetTime(), REDRAW_END);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::SetSurfDlgEnables()
|
||||
{
|
||||
if (!hSurfPanel)
|
||||
return;
|
||||
|
||||
nlassert(ip);
|
||||
|
||||
BOOL oType =(GetSubobjectLevel() == EP_OBJECT) ? TRUE : FALSE;
|
||||
BOOL pType =(GetSubobjectLevel() == EP_PATCH) ? TRUE : FALSE;
|
||||
|
||||
if (oType)
|
||||
return;
|
||||
if (!pType)
|
||||
return;
|
||||
|
||||
ICustButton *but;
|
||||
ISpinnerControl *spin;
|
||||
but = GetICustButton(GetDlgItem(hSurfPanel, IDC_SELECT_BYID));
|
||||
but->Enable(pType);
|
||||
ReleaseICustButton(but);
|
||||
spin = GetISpinner(GetDlgItem(hSurfPanel, IDC_MAT_IDSPIN));
|
||||
spin->Enable(pType);
|
||||
ReleaseISpinner(spin);
|
||||
for (int i = 0; i < 32; ++i)
|
||||
{
|
||||
but = GetICustButton(GetDlgItem(hSurfPanel, IDC_SMOOTH_GRP1 + i));
|
||||
but->Enable(pType);
|
||||
ReleaseICustButton(but);
|
||||
}
|
||||
but = GetICustButton(GetDlgItem(hSurfPanel, IDC_SELECTBYSMOOTH));
|
||||
but->Enable(pType);
|
||||
ReleaseICustButton(but);
|
||||
but = GetICustButton(GetDlgItem(hSurfPanel, IDC_SMOOTH_CLEAR));
|
||||
but->Enable(pType);
|
||||
ReleaseICustButton(but);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::SetTileDlgEnables()
|
||||
{
|
||||
if (!hTilePanel)
|
||||
return;
|
||||
|
||||
nlassert(ip);
|
||||
|
||||
BOOL oType =(GetSubobjectLevel() == EP_OBJECT) ? TRUE : FALSE;
|
||||
BOOL pType =(GetSubobjectLevel() == EP_TILE) ? TRUE : FALSE;
|
||||
|
||||
if (oType)
|
||||
return;
|
||||
if (!pType)
|
||||
return;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::SetEdgeDlgEnables()
|
||||
{
|
||||
if (!hEdgePanel)
|
||||
return;
|
||||
|
||||
nlassert(ip);
|
||||
|
||||
BOOL oType =(GetSubobjectLevel() == EP_OBJECT) ? TRUE : FALSE;
|
||||
BOOL pType =(GetSubobjectLevel() == EP_TILE) ? TRUE : FALSE;
|
||||
|
||||
if (oType)
|
||||
return;
|
||||
if (!pType)
|
||||
return;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
DWORD EditPatchMod::GetSelSmoothBits(DWORD &invalid)
|
||||
{
|
||||
BOOL first = 1;
|
||||
DWORD bits = 0;
|
||||
invalid = 0;
|
||||
ModContextList mcList;
|
||||
INodeTab nodes;
|
||||
|
||||
if (!ip)
|
||||
return 0;
|
||||
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;
|
||||
patchData->BeginEdit(ip->GetTime());
|
||||
RPatchMesh *rpatch;
|
||||
PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch);
|
||||
if (!patch)
|
||||
continue;
|
||||
|
||||
for (int j = 0; j < patch->getNumPatches(); j++)
|
||||
{
|
||||
if (patch->patchSel[j])
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
first = FALSE;
|
||||
bits = patch->patches[j].smGroup;
|
||||
} else
|
||||
{
|
||||
if (patch->patches[j].smGroup != bits)
|
||||
{
|
||||
invalid |= patch->patches[j].smGroup^bits;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
patchData->SetFlag(EPD_BEENDONE, TRUE);
|
||||
}
|
||||
|
||||
nodes.DisposeTemporary();
|
||||
return bits;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
DWORD EditPatchMod::GetUsedSmoothBits()
|
||||
{
|
||||
DWORD bits = 0;
|
||||
ModContextList mcList;
|
||||
INodeTab nodes;
|
||||
|
||||
if (!ip)
|
||||
return 0;
|
||||
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;
|
||||
patchData->BeginEdit(ip->GetTime());
|
||||
RPatchMesh *rpatch;
|
||||
PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(),rpatch);
|
||||
if (!patch)
|
||||
continue;
|
||||
|
||||
for (int j = 0; j < patch->getNumPatches(); j++)
|
||||
{
|
||||
bits |= patch->patches[j].smGroup;
|
||||
}
|
||||
|
||||
patchData->SetFlag(EPD_BEENDONE, TRUE);
|
||||
}
|
||||
|
||||
nodes.DisposeTemporary();
|
||||
return bits;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::SelectBySmoothGroup(DWORD bits, BOOL clear)
|
||||
{
|
||||
ModContextList mcList;
|
||||
INodeTab nodes;
|
||||
|
||||
if (!ip)
|
||||
return;
|
||||
ip->GetModContexts(mcList, nodes);
|
||||
ClearPatchDataFlag(mcList, EPD_BEENDONE);
|
||||
|
||||
theHold.Begin();
|
||||
|
||||
for (int i = 0; i < mcList.Count(); i++)
|
||||
{
|
||||
EditPatchData *patchData =(EditPatchData*)mcList[i]->localData;
|
||||
if (!patchData)
|
||||
continue;
|
||||
if (patchData->GetFlag(EPD_BEENDONE))
|
||||
continue;
|
||||
patchData->BeginEdit(ip->GetTime());
|
||||
RPatchMesh *rpatch;
|
||||
PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(),rpatch);
|
||||
if (!patch)
|
||||
continue;
|
||||
|
||||
// Start a restore object...
|
||||
if (theHold.Holding())
|
||||
{
|
||||
theHold.Put(new PatchSelRestore(patchData, this, patch));
|
||||
}
|
||||
|
||||
if (clear)
|
||||
patch->patchSel.ClearAll();
|
||||
for (int j = 0; j < patch->getNumPatches(); j++)
|
||||
{
|
||||
if (patch->patches[j].smGroup & bits)
|
||||
{
|
||||
patch->patchSel.Set(j);
|
||||
}
|
||||
}
|
||||
|
||||
patchData->UpdateChanges(patch, rpatch, FALSE);
|
||||
patchData->SetFlag(EPD_BEENDONE, TRUE);
|
||||
patchData->TempData(this)->Invalidate(PART_SELECT);
|
||||
}
|
||||
|
||||
PatchSelChanged();
|
||||
theHold.Accept(GetString(IDS_RB_SELECTBYSMOOTH));
|
||||
|
||||
nodes.DisposeTemporary();
|
||||
NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
|
||||
ip->RedrawViews(ip->GetTime());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::SetSelSmoothBits(DWORD bits, DWORD which)
|
||||
{
|
||||
ModContextList mcList;
|
||||
INodeTab nodes;
|
||||
|
||||
if (!ip)
|
||||
return;
|
||||
ip->GetModContexts(mcList, nodes);
|
||||
ClearPatchDataFlag(mcList, EPD_BEENDONE);
|
||||
|
||||
theHold.Begin();
|
||||
|
||||
for (int i = 0; i < mcList.Count(); i++)
|
||||
{
|
||||
EditPatchData *patchData =(EditPatchData*)mcList[i]->localData;
|
||||
if (!patchData)
|
||||
continue;
|
||||
if (patchData->GetFlag(EPD_BEENDONE))
|
||||
continue;
|
||||
patchData->BeginEdit(ip->GetTime());
|
||||
RPatchMesh *rpatch;
|
||||
PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(),rpatch);
|
||||
if (!patch)
|
||||
continue;
|
||||
|
||||
// Start a restore object...
|
||||
if (theHold.Holding())
|
||||
{
|
||||
theHold.Put(new PatchSelRestore(patchData, this, patch));
|
||||
}
|
||||
|
||||
for (int j = 0; j < patch->getNumPatches(); j++)
|
||||
{
|
||||
if (patch->patchSel[j])
|
||||
{
|
||||
patch->patches[j].smGroup &= ~which;
|
||||
patch->patches[j].smGroup |= bits&which;
|
||||
}
|
||||
}
|
||||
|
||||
patchData->UpdateChanges(patch, rpatch, FALSE);
|
||||
patchData->SetFlag(EPD_BEENDONE, TRUE);
|
||||
patchData->TempData(this)->Invalidate(PART_SELECT);
|
||||
}
|
||||
|
||||
PatchSelChanged();
|
||||
theHold.Accept(GetString(IDS_RB_SETSMOOTHGROUP));
|
||||
|
||||
nodes.DisposeTemporary();
|
||||
NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
|
||||
InvalidateSurfaceUI();
|
||||
ip->RedrawViews(ip->GetTime());
|
||||
}
|
||||
|
@ -1,956 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
#define PROMPT_TIME 2000
|
||||
|
||||
extern AdvParams sParams;
|
||||
BOOL CALLBACK AdvParametersDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::SetTessUI(HWND hDlg, TessApprox *tess)
|
||||
{
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_U), FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_U_SPINNER), FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_V), FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_V_SPINNER), FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_EDGE), FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_EDGE_SPINNER), FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_DIST), FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_DIST_SPINNER), FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_ANG), FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_ANG_SPINNER), FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_ADVANCED_PARAMETERS), FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_NORMALS), FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_VIEW_DEP), FALSE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_WELDTESS), FALSE);
|
||||
|
||||
CheckDlgButton(hDlg, IDC_TESS_SET, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_TESS_REGULAR, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_TESS_PARAM, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_TESS_SPATIAL, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_TESS_CURV, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_TESS_LDA, FALSE);
|
||||
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_TESS_VIEW_DEP), SW_HIDE);
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_TESS_NORMALS), SW_HIDE);
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_WELDTESS), SW_HIDE);
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_MESH), SW_HIDE);
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_DISP), SW_HIDE);
|
||||
|
||||
// watje 12-10-98
|
||||
if (tess->showInteriorFaces)
|
||||
CheckDlgButton(hDlg, IDC_SHOW_INTERIOR_FACES, TRUE);
|
||||
else CheckDlgButton(hDlg, IDC_SHOW_INTERIOR_FACES, FALSE);
|
||||
if (tileMode)
|
||||
{
|
||||
CheckDlgButton(hDlg, IDC_TILE_MODE, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckDlgButton(hDlg, IDC_TILE_MODE, FALSE);
|
||||
}
|
||||
// Old
|
||||
BOOL bCheck=(IsDlgButtonChecked(hDlg, IDC_TILE_MODE)==BST_CHECKED);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_STEPS), !bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_STEPSSPINNER), !bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_STEPS_RENDER), !bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_STEPSRENDERSPINNER), !bCheck);
|
||||
|
||||
// New
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_TILESTEPS), bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_TILESTEPSSPINNER), bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_TRANSITION), bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_TRANSITIONSPINNER), bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_KEEP_MAPPING), bCheck);
|
||||
|
||||
if (keepMapping)
|
||||
CheckDlgButton(hDlg, IDC_KEEP_MAPPING, TRUE);
|
||||
else
|
||||
CheckDlgButton(hDlg, IDC_KEEP_MAPPING, FALSE);
|
||||
|
||||
switch (tess->type)
|
||||
{
|
||||
case TESS_SET:
|
||||
CheckDlgButton(hDlg, IDC_TESS_SET, TRUE);
|
||||
mergeSpin->Disable();
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_SHOW_INTERIOR_FACES), TRUE);
|
||||
break;
|
||||
|
||||
case TESS_REGULAR:
|
||||
CheckDlgButton(hDlg, IDC_TESS_REGULAR, TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_U), TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_U_SPINNER), TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_V), TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_V_SPINNER), TRUE);
|
||||
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_TESS_VIEW_DEP), SW_HIDE);
|
||||
mergeSpin->Enable();
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_SHOW_INTERIOR_FACES), FALSE);
|
||||
break;
|
||||
|
||||
case TESS_PARAM:
|
||||
CheckDlgButton(hDlg, IDC_TESS_PARAM, TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_U), TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_U_SPINNER), TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_V), TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_V_SPINNER), TRUE);
|
||||
|
||||
mergeSpin->Enable();
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_SHOW_INTERIOR_FACES), FALSE);
|
||||
break;
|
||||
|
||||
case TESS_SPATIAL:
|
||||
CheckDlgButton(hDlg, IDC_TESS_SPATIAL, TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_EDGE), TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_EDGE_SPINNER), TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_VIEW_DEP), TRUE);
|
||||
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_VIEW_DEP), !settingViewportTess);
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_TESS_VIEW_DEP), settingViewportTess?SW_HIDE:SW_SHOW);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_ADVANCED_PARAMETERS), TRUE);
|
||||
mergeSpin->Enable();
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_SHOW_INTERIOR_FACES), FALSE);
|
||||
break;
|
||||
|
||||
case TESS_CURVE:
|
||||
CheckDlgButton(hDlg, IDC_TESS_CURV, TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_DIST), TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_DIST_SPINNER), TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_ANG), TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_ANG_SPINNER), TRUE);
|
||||
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_VIEW_DEP), !settingViewportTess);
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_TESS_VIEW_DEP), settingViewportTess?SW_HIDE:SW_SHOW);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_ADVANCED_PARAMETERS), TRUE);
|
||||
mergeSpin->Enable();
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_SHOW_INTERIOR_FACES), FALSE);
|
||||
break;
|
||||
|
||||
case TESS_LDA:
|
||||
CheckDlgButton(hDlg, IDC_TESS_LDA, TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_EDGE), TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_EDGE_SPINNER), TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_DIST), TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_DIST_SPINNER), TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_ANG), TRUE);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_ANG_SPINNER), TRUE);
|
||||
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_VIEW_DEP), !settingViewportTess);
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_TESS_VIEW_DEP), settingViewportTess?SW_HIDE:SW_SHOW);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_ADVANCED_PARAMETERS), TRUE);
|
||||
mergeSpin->Enable();
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_SHOW_INTERIOR_FACES), FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (settingViewportTess)
|
||||
{
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_TESS_SET), SW_SHOW);
|
||||
|
||||
if (tess->type != TESS_SET)
|
||||
{
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_TESS_NORMALS), SW_SHOW);
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_WELDTESS), SW_SHOW);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_NORMALS), !GetViewTessWeld());
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_WELDTESS), tess->merge > 0.0f);
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (settingDisp)
|
||||
{
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_MESH), SW_SHOW);
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_DISP), SW_SHOW);
|
||||
} else
|
||||
{
|
||||
if (tess->type != TESS_SET)
|
||||
{
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_MESH), SW_SHOW);
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_DISP), SW_SHOW);
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_TESS_NORMALS), SW_SHOW);
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_WELDTESS), SW_SHOW);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_NORMALS), !GetProdTessWeld());
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_WELDTESS), tess->merge > 0.0f);
|
||||
CheckDlgButton(hDlg, IDC_MESH, TRUE);
|
||||
}
|
||||
ShowWindow(GetDlgItem(hDlg, IDC_TESS_SET), SW_SHOW);
|
||||
}
|
||||
}
|
||||
|
||||
// now set all the settings
|
||||
uSpin->SetValue(tess->u, FALSE);
|
||||
vSpin->SetValue(tess->v, FALSE);
|
||||
edgeSpin->SetValue(tess->edge, FALSE);
|
||||
distSpin->SetValue(tess->dist, FALSE);
|
||||
angSpin->SetValue(tess->ang, FALSE);
|
||||
mergeSpin->SetValue(tess->merge, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_TESS_VIEW_DEP, tess->view);
|
||||
if (settingViewportTess)
|
||||
{
|
||||
CheckDlgButton(hDlg, IDC_TESS_VIEW, TRUE);
|
||||
CheckDlgButton(hDlg, IDC_TESS_RENDERER, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_TESS_NORMALS, GetViewTessNormals());
|
||||
CheckDlgButton(hDlg, IDC_WELDTESS, GetViewTessWeld());
|
||||
} else
|
||||
{
|
||||
CheckDlgButton(hDlg, IDC_TESS_VIEW, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_TESS_RENDERER, TRUE);
|
||||
CheckDlgButton(hDlg, IDC_TESS_NORMALS, GetProdTessNormals());
|
||||
CheckDlgButton(hDlg, IDC_WELDTESS, GetProdTessWeld());
|
||||
}
|
||||
CheckDlgButton(hDlg, IDC_DISP, settingDisp);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL CALLBACK PatchObjSurfDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
EditPatchMod *ep =(EditPatchMod *)GetWindowLong(hDlg, GWL_USERDATA);
|
||||
if (!ep && message != WM_INITDIALOG)
|
||||
return FALSE;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
|
||||
ep =(EditPatchMod *)lParam;
|
||||
ep->hSurfPanel = hDlg;
|
||||
SetWindowLong(hDlg, GWL_USERDATA, (LONG)ep);
|
||||
if (!ep->settingViewportTess && ep->settingDisp && ep->GetProdTess().type == TESS_SET)
|
||||
ep->settingDisp = FALSE;
|
||||
TessApprox t;
|
||||
if (ep->settingViewportTess)
|
||||
{
|
||||
t = ep->GetViewTess();
|
||||
} else
|
||||
{
|
||||
if (ep->settingDisp)
|
||||
t = ep->GetDispTess();
|
||||
else
|
||||
t = ep->GetProdTess();
|
||||
}
|
||||
ep->uSpin = SetupIntSpinner(hDlg, IDC_TESS_U_SPINNER, IDC_TESS_U, 1, 100, t.u);
|
||||
ep->vSpin = SetupIntSpinner(hDlg, IDC_TESS_V_SPINNER, IDC_TESS_V, 1, 100, t.v);
|
||||
#define MAX_F 1000.0f
|
||||
ep->edgeSpin = SetupFloatSpinner(hDlg, IDC_TESS_EDGE_SPINNER, IDC_TESS_EDGE, 0.0f, MAX_F, t.edge);
|
||||
ep->distSpin = SetupFloatSpinner(hDlg, IDC_TESS_DIST_SPINNER, IDC_TESS_DIST, 0.0f, MAX_F, t.dist);
|
||||
ep->angSpin = SetupFloatSpinner(hDlg, IDC_TESS_ANG_SPINNER, IDC_TESS_ANG, 0.0f, MAX_F, t.ang);
|
||||
ep->mergeSpin = SetupFloatSpinner(hDlg, IDC_MERGE_SPINNER, IDC_MERGE, 0.000f, MAX_F, t.merge);
|
||||
ep->SetTessUI(hDlg, &t);
|
||||
ep->SetSurfDlgEnables();
|
||||
ep->SetTileDlgEnables();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_DESTROY:
|
||||
if (ep->uSpin)
|
||||
{
|
||||
ReleaseISpinner(ep->uSpin);
|
||||
ep->uSpin = NULL;
|
||||
}
|
||||
if (ep->vSpin)
|
||||
{
|
||||
ReleaseISpinner(ep->vSpin);
|
||||
ep->vSpin = NULL;
|
||||
}
|
||||
if (ep->edgeSpin)
|
||||
{
|
||||
ReleaseISpinner(ep->edgeSpin);
|
||||
ep->edgeSpin = NULL;
|
||||
}
|
||||
if (ep->distSpin)
|
||||
{
|
||||
ReleaseISpinner(ep->distSpin);
|
||||
ep->distSpin = NULL;
|
||||
}
|
||||
if (ep->angSpin)
|
||||
{
|
||||
ReleaseISpinner(ep->angSpin);
|
||||
ep->angSpin = NULL;
|
||||
}
|
||||
if (ep->mergeSpin)
|
||||
{
|
||||
ReleaseISpinner(ep->mergeSpin);
|
||||
ep->mergeSpin = NULL;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case CC_SPINNER_BUTTONUP:
|
||||
{
|
||||
TessApprox tess;
|
||||
if (ep->settingViewportTess)
|
||||
{
|
||||
tess = ep->GetViewTess();
|
||||
} else
|
||||
{
|
||||
if (ep->settingDisp)
|
||||
tess = ep->GetDispTess();
|
||||
else
|
||||
tess = ep->GetProdTess();
|
||||
}
|
||||
ep->SetTessUI(hDlg, &tess);
|
||||
}
|
||||
break;
|
||||
|
||||
case CC_SPINNER_CHANGE:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_TESS_U_SPINNER:
|
||||
case IDC_TESS_V_SPINNER:
|
||||
case IDC_TESS_EDGE_SPINNER:
|
||||
case IDC_TESS_DIST_SPINNER:
|
||||
case IDC_TESS_ANG_SPINNER:
|
||||
case IDC_MERGE_SPINNER:
|
||||
{
|
||||
TessApprox tess;
|
||||
if (ep->settingViewportTess)
|
||||
{
|
||||
tess = ep->GetViewTess();
|
||||
} else
|
||||
{
|
||||
if (ep->settingDisp)
|
||||
tess = ep->GetDispTess();
|
||||
else
|
||||
tess = ep->GetProdTess();
|
||||
}
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_TESS_U_SPINNER:
|
||||
tess.u = ep->uSpin->GetIVal();
|
||||
break;
|
||||
case IDC_TESS_V_SPINNER:
|
||||
tess.v = ep->vSpin->GetIVal();
|
||||
break;
|
||||
case IDC_TESS_EDGE_SPINNER:
|
||||
tess.edge = ep->edgeSpin->GetFVal();
|
||||
break;
|
||||
case IDC_TESS_DIST_SPINNER:
|
||||
tess.dist = ep->distSpin->GetFVal();
|
||||
break;
|
||||
case IDC_TESS_ANG_SPINNER:
|
||||
tess.ang = ep->angSpin->GetFVal();
|
||||
break;
|
||||
case IDC_MERGE_SPINNER:
|
||||
tess.merge = ep->mergeSpin->GetFVal();
|
||||
break;
|
||||
}
|
||||
if (ep->settingViewportTess)
|
||||
{
|
||||
ep->SetViewTess(tess);
|
||||
} else
|
||||
{
|
||||
if (ep->settingDisp)
|
||||
ep->SetDispTess(tess);
|
||||
else
|
||||
ep->SetProdTess(tess);
|
||||
}
|
||||
if (!HIWORD(wParam))
|
||||
ep->SetTessUI(hDlg, &tess);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_MOUSEMOVE:
|
||||
ep->ip->RollupMouseMessage(hDlg, message, wParam, lParam);
|
||||
return FALSE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
// Tessellation
|
||||
case IDC_TESS_VIEW:
|
||||
{
|
||||
ep->settingViewportTess = TRUE;
|
||||
TessApprox t = ep->GetViewTess();
|
||||
ep->SetTessUI(hDlg, &t);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_TESS_VIEW_DEP), FALSE); // always off here
|
||||
break;
|
||||
}
|
||||
case IDC_TESS_RENDERER:
|
||||
{
|
||||
ep->settingViewportTess = FALSE;
|
||||
if (ep->settingDisp)
|
||||
{
|
||||
TessApprox t = ep->GetDispTess();
|
||||
ep->SetTessUI(hDlg, &t);
|
||||
} else
|
||||
{
|
||||
TessApprox t = ep->GetProdTess();
|
||||
ep->SetTessUI(hDlg, &t);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IDC_MESH:
|
||||
ep->settingDisp = FALSE;
|
||||
ep->SetTessUI(hDlg, &ep->GetProdTess());
|
||||
break;
|
||||
case IDC_DISP:
|
||||
ep->settingDisp = TRUE;
|
||||
ep->SetTessUI(hDlg, &ep->GetDispTess());
|
||||
break;
|
||||
case IDC_TILE_MODE:
|
||||
{
|
||||
BOOL bCheck=(IsDlgButtonChecked(hDlg, IDC_TILE_MODE)==BST_CHECKED);
|
||||
ep->SetTileMode (bCheck!=0);
|
||||
|
||||
// Old
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_STEPS), !bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_STEPSSPINNER), !bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_STEPS_RENDER), !bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_STEPSRENDERSPINNER), !bCheck);
|
||||
|
||||
// New
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_TILESTEPS), bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_TILESTEPSSPINNER), bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_TRANSITION), bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_TRANSITIONSPINNER), bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_KEEP_MAPPING), bCheck);
|
||||
|
||||
ep->SetTessUI(hDlg, &ep->GetDispTess());
|
||||
}
|
||||
break;
|
||||
case IDC_KEEP_MAPPING:
|
||||
ep->SetKeepMapping (IsDlgButtonChecked(hDlg, IDC_KEEP_MAPPING)!=0);
|
||||
ep->SetTessUI(hDlg, &ep->GetDispTess());
|
||||
break;
|
||||
// watje 12-10-98
|
||||
case IDC_SHOW_INTERIOR_FACES:
|
||||
case IDC_TESS_SET:
|
||||
case IDC_TESS_REGULAR:
|
||||
case IDC_TESS_PARAM:
|
||||
case IDC_TESS_SPATIAL:
|
||||
case IDC_TESS_CURV:
|
||||
case IDC_TESS_LDA:
|
||||
{
|
||||
TessApprox tess;
|
||||
if (ep->settingViewportTess)
|
||||
{
|
||||
tess = ep->GetViewTess();
|
||||
} else
|
||||
{
|
||||
if (ep->settingDisp)
|
||||
tess = ep->GetDispTess();
|
||||
else
|
||||
tess = ep->GetProdTess();
|
||||
}
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
// watje 12-10-98
|
||||
case IDC_SHOW_INTERIOR_FACES:
|
||||
tess.showInteriorFaces = IsDlgButtonChecked(hDlg, IDC_SHOW_INTERIOR_FACES);
|
||||
break;
|
||||
case IDC_TESS_SET:
|
||||
tess.type = TESS_SET;
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_SHOW_INTERIOR_FACES), TRUE);
|
||||
break;
|
||||
case IDC_TESS_REGULAR:
|
||||
tess.type = TESS_REGULAR;
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_SHOW_INTERIOR_FACES), TRUE);
|
||||
break;
|
||||
case IDC_TESS_PARAM:
|
||||
tess.type = TESS_PARAM;
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_SHOW_INTERIOR_FACES), TRUE);
|
||||
break;
|
||||
case IDC_TESS_SPATIAL:
|
||||
tess.type = TESS_SPATIAL;
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_SHOW_INTERIOR_FACES), TRUE);
|
||||
break;
|
||||
case IDC_TESS_CURV:
|
||||
tess.type = TESS_CURVE;
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_SHOW_INTERIOR_FACES), TRUE);
|
||||
break;
|
||||
case IDC_TESS_LDA:
|
||||
tess.type = TESS_LDA;
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_SHOW_INTERIOR_FACES), TRUE);
|
||||
break;
|
||||
}
|
||||
if (ep->settingViewportTess)
|
||||
{
|
||||
ep->SetViewTess(tess);
|
||||
} else
|
||||
{
|
||||
if (ep->settingDisp)
|
||||
ep->SetDispTess(tess);
|
||||
else
|
||||
ep->SetProdTess(tess);
|
||||
}
|
||||
ep->SetTessUI(hDlg, &tess);
|
||||
}
|
||||
break;
|
||||
case IDC_TESS_VIEW_DEP:
|
||||
{
|
||||
TessApprox tess;
|
||||
tess = ep->GetProdTess();
|
||||
tess.view = IsDlgButtonChecked(hDlg, IDC_TESS_VIEW_DEP);
|
||||
if (ep->settingDisp)
|
||||
ep->SetDispTess(tess);
|
||||
else
|
||||
ep->SetProdTess(tess);
|
||||
}
|
||||
break;
|
||||
case IDC_TESS_NORMALS:
|
||||
if (ep->settingViewportTess)
|
||||
{
|
||||
ep->SetViewTessNormals(IsDlgButtonChecked(hDlg, IDC_TESS_NORMALS));
|
||||
ep->SetTessUI(hDlg, &ep->GetViewTess());
|
||||
} else
|
||||
{
|
||||
ep->SetProdTessNormals(IsDlgButtonChecked(hDlg, IDC_TESS_NORMALS));
|
||||
if (ep->settingDisp)
|
||||
ep->SetTessUI(hDlg, &ep->GetDispTess());
|
||||
else
|
||||
ep->SetTessUI(hDlg, &ep->GetProdTess());
|
||||
}
|
||||
break;
|
||||
case IDC_WELDTESS:
|
||||
if (ep->settingViewportTess)
|
||||
{
|
||||
ep->SetViewTessWeld(IsDlgButtonChecked(hDlg, IDC_WELDTESS));
|
||||
ep->SetTessUI(hDlg, &ep->GetViewTess());
|
||||
} else
|
||||
{
|
||||
ep->SetProdTessWeld(IsDlgButtonChecked(hDlg, IDC_WELDTESS));
|
||||
if (ep->settingDisp)
|
||||
ep->SetTessUI(hDlg, &ep->GetDispTess());
|
||||
else
|
||||
ep->SetTessUI(hDlg, &ep->GetProdTess());
|
||||
}
|
||||
break;
|
||||
case IDC_ADVANCED_PARAMETERS:
|
||||
{
|
||||
TessApprox tess;
|
||||
if (ep->settingViewportTess)
|
||||
{
|
||||
tess = ep->GetViewTess();
|
||||
} else
|
||||
{
|
||||
if (ep->settingDisp)
|
||||
tess = ep->GetDispTess();
|
||||
else
|
||||
tess = ep->GetProdTess();
|
||||
}
|
||||
sParams.mStyle = tess.subdiv;
|
||||
sParams.mMin = tess.minSub;
|
||||
sParams.mMax = tess.maxSub;
|
||||
sParams.mTris = tess.maxTris;
|
||||
int retval = DialogBox(hInstance,
|
||||
MAKEINTRESOURCE(IDD_SURF_APPROX_ADV),
|
||||
ep->ip->GetMAXHWnd(), AdvParametersDialogProc);
|
||||
if (retval == 1)
|
||||
{
|
||||
BOOL confirm = FALSE;
|
||||
if ((sParams.mStyle == SUBDIV_DELAUNAY && sParams.mTris > 200000) ||
|
||||
(sParams.mStyle != SUBDIV_DELAUNAY && sParams.mMax > 5))
|
||||
{
|
||||
// warning!
|
||||
TSTR title = GetString(IDS_ADV_SURF_APPROX_WARNING_TITLE),
|
||||
warning = GetString(IDS_ADV_SURF_APPROX_WARNING);
|
||||
if (MessageBox(hDlg, warning, title,
|
||||
MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2) == IDYES)
|
||||
confirm = TRUE;
|
||||
|
||||
} else
|
||||
confirm = TRUE;
|
||||
if (confirm)
|
||||
{
|
||||
// do it, they've been warned!
|
||||
tess.subdiv = sParams.mStyle;
|
||||
tess.minSub = sParams.mMin;
|
||||
tess.maxSub = sParams.mMax;
|
||||
tess.maxTris = sParams.mTris;
|
||||
if (ep->settingViewportTess)
|
||||
{
|
||||
ep->SetViewTess(tess);
|
||||
} else
|
||||
{
|
||||
if (ep->settingDisp)
|
||||
ep->SetDispTess(tess);
|
||||
else
|
||||
ep->SetProdTess(tess);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
AdvParams sParams;
|
||||
static ISpinnerControl* psMinSpin = NULL;
|
||||
static ISpinnerControl* psMaxSpin = NULL;
|
||||
static ISpinnerControl* psMaxTrisSpin = NULL;
|
||||
// this max matches the MI max.
|
||||
#define MAX_SUBDIV 7
|
||||
static BOOL initing = FALSE; // this is a hack but CenterWindow causes bad commands
|
||||
BOOL CALLBACK
|
||||
AdvParametersDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
initing = TRUE;
|
||||
CenterWindow(hDlg, GetCOREInterface()->GetMAXHWnd());
|
||||
initing = FALSE;
|
||||
psMinSpin = SetupIntSpinner(hDlg, IDC_TESS_MIN_REC_SPINNER, IDC_TESS_MIN_REC, 0, sParams.mMax, sParams.mMin);
|
||||
psMaxSpin = SetupIntSpinner(hDlg, IDC_TESS_MAX_REC_SPINNER, IDC_TESS_MAX_REC, sParams.mMin, MAX_SUBDIV, sParams.mMax);
|
||||
psMaxTrisSpin = SetupIntSpinner(hDlg, IDC_TESS_MAX_TRIS_SPINNER, IDC_TESS_MAX_TRIS, 0, 2000000, sParams.mTris);
|
||||
switch (sParams.mStyle)
|
||||
{
|
||||
case SUBDIV_GRID:
|
||||
CheckDlgButton(hDlg, IDC_GRID, TRUE);
|
||||
CheckDlgButton(hDlg, IDC_TREE, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_DELAUNAY, FALSE);
|
||||
break;
|
||||
case SUBDIV_TREE:
|
||||
CheckDlgButton(hDlg, IDC_GRID, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_TREE, TRUE);
|
||||
CheckDlgButton(hDlg, IDC_DELAUNAY, FALSE);
|
||||
break;
|
||||
case SUBDIV_DELAUNAY:
|
||||
CheckDlgButton(hDlg, IDC_GRID, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_TREE, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_DELAUNAY, TRUE);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_COMMAND:
|
||||
if (initing)
|
||||
return FALSE;
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDOK:
|
||||
EndDialog(hDlg, 1);
|
||||
break;
|
||||
case IDCANCEL:
|
||||
EndDialog(hDlg, 0);
|
||||
break;
|
||||
case IDC_GRID:
|
||||
sParams.mStyle = SUBDIV_GRID;
|
||||
CheckDlgButton(hDlg, IDC_GRID, TRUE);
|
||||
CheckDlgButton(hDlg, IDC_TREE, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_DELAUNAY, FALSE);
|
||||
break;
|
||||
case IDC_TREE:
|
||||
sParams.mStyle = SUBDIV_TREE;
|
||||
CheckDlgButton(hDlg, IDC_GRID, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_TREE, TRUE);
|
||||
CheckDlgButton(hDlg, IDC_DELAUNAY, FALSE);
|
||||
break;
|
||||
case IDC_DELAUNAY:
|
||||
sParams.mStyle = SUBDIV_DELAUNAY;
|
||||
CheckDlgButton(hDlg, IDC_GRID, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_TREE, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_DELAUNAY, TRUE);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case CC_SPINNER_CHANGE:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_TESS_MIN_REC_SPINNER:
|
||||
sParams.mMin = psMinSpin->GetIVal();
|
||||
psMinSpin->SetLimits(0, sParams.mMax, FALSE);
|
||||
psMaxSpin->SetLimits(sParams.mMin, MAX_SUBDIV, FALSE);
|
||||
break;
|
||||
case IDC_TESS_MAX_REC_SPINNER:
|
||||
sParams.mMax = psMaxSpin->GetIVal();
|
||||
psMinSpin->SetLimits(0, sParams.mMax, FALSE);
|
||||
psMaxSpin->SetLimits(sParams.mMin, MAX_SUBDIV, FALSE);
|
||||
break;
|
||||
case IDC_TESS_MAX_TRIS_SPINNER:
|
||||
sParams.mTris = psMaxTrisSpin->GetIVal();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
if (psMinSpin)
|
||||
{
|
||||
ReleaseISpinner(psMinSpin);
|
||||
psMinSpin = NULL;
|
||||
}
|
||||
if (psMaxSpin)
|
||||
{
|
||||
ReleaseISpinner(psMaxSpin);
|
||||
psMaxSpin = NULL;
|
||||
}
|
||||
if (psMaxTrisSpin)
|
||||
{
|
||||
ReleaseISpinner(psMaxTrisSpin);
|
||||
psMaxTrisSpin = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::SetViewTess(TessApprox &tess)
|
||||
{
|
||||
viewTess = tess;
|
||||
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;
|
||||
|
||||
patch->SetViewTess(tess);
|
||||
patchData->viewTess = tess;
|
||||
//rpatch->rTess = rTess;
|
||||
if (patchData->tempData)
|
||||
{
|
||||
patchData->TempData(this)->Invalidate(PART_DISPLAY);
|
||||
}
|
||||
}
|
||||
nodes.DisposeTemporary();
|
||||
NotifyDependents(FOREVER, PART_DISPLAY, REFMSG_CHANGE);
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::SetProdTess(TessApprox &tess)
|
||||
{
|
||||
prodTess = tess;
|
||||
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;
|
||||
|
||||
patch->SetProdTess(tess);
|
||||
patchData->prodTess = tess;
|
||||
if (patchData->tempData)
|
||||
{
|
||||
patchData->TempData(this)->Invalidate(PART_DISPLAY);
|
||||
}
|
||||
}
|
||||
nodes.DisposeTemporary();
|
||||
NotifyDependents(FOREVER, PART_DISPLAY, REFMSG_CHANGE);
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::SetDispTess(TessApprox &tess)
|
||||
{
|
||||
dispTess = tess;
|
||||
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;
|
||||
|
||||
patch->SetDispTess(tess);
|
||||
patchData->dispTess = tess;
|
||||
if (patchData->tempData)
|
||||
{
|
||||
patchData->TempData(this)->Invalidate(PART_DISPLAY);
|
||||
}
|
||||
}
|
||||
nodes.DisposeTemporary();
|
||||
NotifyDependents(FOREVER, PART_DISPLAY, REFMSG_CHANGE);
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::SetViewTessNormals(BOOL use)
|
||||
{
|
||||
mViewTessNormals = use;
|
||||
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;
|
||||
|
||||
patch->SetViewTessNormals(use);
|
||||
patchData->mViewTessNormals = use;
|
||||
if (patchData->tempData)
|
||||
{
|
||||
patchData->TempData(this)->Invalidate(PART_DISPLAY);
|
||||
}
|
||||
}
|
||||
nodes.DisposeTemporary();
|
||||
NotifyDependents(FOREVER, PART_DISPLAY, REFMSG_CHANGE);
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::SetProdTessNormals(BOOL use)
|
||||
{
|
||||
mProdTessNormals = use;
|
||||
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;
|
||||
|
||||
patch->SetProdTessNormals(use);
|
||||
patchData->mProdTessNormals = use;
|
||||
if (patchData->tempData)
|
||||
{
|
||||
patchData->TempData(this)->Invalidate(PART_DISPLAY);
|
||||
}
|
||||
}
|
||||
nodes.DisposeTemporary();
|
||||
NotifyDependents(FOREVER, PART_DISPLAY, REFMSG_CHANGE);
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::SetViewTessWeld(BOOL weld)
|
||||
{
|
||||
mViewTessWeld = weld;
|
||||
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;
|
||||
|
||||
patch->SetViewTessWeld(weld);
|
||||
patchData->mViewTessWeld = weld;
|
||||
if (patchData->tempData)
|
||||
{
|
||||
patchData->TempData(this)->Invalidate(PART_DISPLAY);
|
||||
}
|
||||
}
|
||||
nodes.DisposeTemporary();
|
||||
NotifyDependents(FOREVER, PART_DISPLAY, REFMSG_CHANGE);
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::SetProdTessWeld(BOOL weld)
|
||||
{
|
||||
mProdTessWeld = weld;
|
||||
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;
|
||||
|
||||
patch->SetProdTessWeld(weld);
|
||||
patchData->mProdTessWeld = weld;
|
||||
if (patchData->tempData)
|
||||
{
|
||||
patchData->TempData(this)->Invalidate(PART_DISPLAY);
|
||||
}
|
||||
}
|
||||
nodes.DisposeTemporary();
|
||||
NotifyDependents(FOREVER, PART_DISPLAY, REFMSG_CHANGE);
|
||||
ip->RedrawViews(ip->GetTime(), REDRAW_NORMAL);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -1,301 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
extern Point3 zeroPoint;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
EPVertMapper::~EPVertMapper()
|
||||
{
|
||||
if (vertMap)
|
||||
{
|
||||
delete[] vertMap;
|
||||
vertMap = NULL;
|
||||
}
|
||||
if (vecMap)
|
||||
{
|
||||
delete[] vecMap;
|
||||
vecMap = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void EPVertMapper::Build(PatchMesh &patch)
|
||||
{
|
||||
verts = patch.numVerts;
|
||||
if (vertMap)
|
||||
delete[] vertMap;
|
||||
vertMap = new EPMapVert[verts];
|
||||
vecs = patch.numVecs;
|
||||
if (vecMap)
|
||||
delete[] vecMap;
|
||||
vecMap = new EPMapVert[vecs];
|
||||
int i;
|
||||
for (i = 0; i < verts; ++i)
|
||||
vertMap[i] = EPMapVert(i, patch.verts[i].p, zeroPoint);
|
||||
for (i = 0; i < vecs; ++i)
|
||||
vecMap[i] = EPMapVert(i, patch.vecs[i].p, zeroPoint);
|
||||
}
|
||||
|
||||
void EPVertMapper::RecordTopologyTags(PatchMesh &patch)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < verts; ++i)
|
||||
{
|
||||
// If it's still mapped, record it!
|
||||
if (vertMap[i].vert >= 0)
|
||||
patch.verts[vertMap[i].vert].aux1 = i;
|
||||
}
|
||||
for (i = 0; i < vecs; ++i)
|
||||
{
|
||||
// If it's still mapped, record it!
|
||||
if (vecMap[i].vert >= 0)
|
||||
patch.vecs[vecMap[i].vert].aux1 = i;
|
||||
}
|
||||
}
|
||||
|
||||
void EPVertMapper::UpdateMapping(PatchMesh &patch)
|
||||
{
|
||||
// Flush existing mapping
|
||||
int i;
|
||||
for (i = 0; i < verts; ++i)
|
||||
vertMap[i].vert = -1;
|
||||
for (i = 0; i < vecs; ++i)
|
||||
vecMap[i].vert = -1;
|
||||
// Build the new mapping
|
||||
int verts = patch.numVerts;
|
||||
for (int vert = 0; vert < verts; ++vert)
|
||||
{
|
||||
int aux = patch.verts[vert].aux1;
|
||||
if (aux != 0xffffffff)
|
||||
vertMap[aux].vert = vert;
|
||||
}
|
||||
int vecs = patch.numVecs;
|
||||
for (int vec = 0; vec < vecs; ++vec)
|
||||
{
|
||||
int aux = patch.vecs[vec].aux1;
|
||||
if (aux != 0xffffffff)
|
||||
vecMap[aux].vert = vec;
|
||||
}
|
||||
}
|
||||
|
||||
void EPVertMapper::RecomputeDeltas(PatchMesh &patch)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < verts; ++i)
|
||||
{
|
||||
EPMapVert &map = vertMap[i];
|
||||
if (map.vert >= 0 && map.originalStored)
|
||||
{
|
||||
Point3 pnew = patch.verts[map.vert].p;
|
||||
#ifdef VMAP_DEBUG
|
||||
Point3 oldDelta = map.delta;
|
||||
#endif
|
||||
map.delta = pnew - map.original;
|
||||
#ifdef VMAP_DEBUG
|
||||
if (map.delta != oldDelta)
|
||||
DebugPrint("Vert %d delta changed from %.2f %.2f %.2f to %.2 %.2f %.2f\n", i, oldDelta.x, oldDelta.y, oldDelta.z, map.delta.x, map.delta.y, map.delta.z);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
for (i = 0; i < vecs; ++i)
|
||||
{
|
||||
EPMapVert &map = vecMap[i];
|
||||
if (map.vert >= 0 && map.originalStored)
|
||||
{
|
||||
Point3 pnew = patch.vecs[map.vert].p;
|
||||
#ifdef VMAP_DEBUG
|
||||
Point3 oldDelta = map.delta;
|
||||
#endif
|
||||
map.delta = pnew - map.original;
|
||||
#ifdef VMAP_DEBUG
|
||||
if (map.delta != oldDelta)
|
||||
DebugPrint("Vec %d delta changed from %.2f %.2f %.2f to %.2 %.2f %.2f\n", i, oldDelta.x, oldDelta.y, oldDelta.z, map.delta.x, map.delta.y, map.delta.z);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EPVertMapper::UpdateAndApplyDeltas(PatchMesh &inPatch, PatchMesh &outPatch)
|
||||
{
|
||||
|
||||
// watje 4-27-99 here to handle 0 patch situations
|
||||
if (inPatch.numPatches == 0)
|
||||
{
|
||||
// outPatch.setNumVerts(0,TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Update the original point locations
|
||||
int i;
|
||||
for (i = 0; i < verts; ++i)
|
||||
{
|
||||
// If this table has more in it than we need, forget the rest
|
||||
// This can happen if the input object changes to fewer verts
|
||||
if (i >= inPatch.numVerts)
|
||||
break;
|
||||
// If it's still mapped, update it!
|
||||
if (vertMap[i].vert >= 0)
|
||||
{
|
||||
vertMap[i].original = inPatch.verts[i].p;
|
||||
vertMap[i].originalStored = TRUE;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < vecs; ++i)
|
||||
{
|
||||
// If this table has more in it than we need, forget the rest
|
||||
// This can happen if the input object changes to fewer vecs
|
||||
if (i >= inPatch.numVecs)
|
||||
break;
|
||||
// If it's still mapped, update it!
|
||||
if (vecMap[i].vert >= 0)
|
||||
{
|
||||
vecMap[i].original = inPatch.vecs[i].p;
|
||||
vecMap[i].originalStored = TRUE;
|
||||
}
|
||||
}
|
||||
// Now apply to output
|
||||
for (i = 0; i < verts; ++i)
|
||||
{
|
||||
EPMapVert &pv = vertMap[i];
|
||||
if (pv.vert >= 0 && pv.originalStored)
|
||||
{
|
||||
// nlassert(pv.vert >= 0 && pv.vert < outPatch.numVerts);
|
||||
// watje 4-27-99 instead just throwing an nlassert it pops a message box up and troes to recover
|
||||
if (!(pv.vert >= 0 && pv.vert < outPatch.numVerts))
|
||||
{
|
||||
outPatch.setNumVerts(pv.vert + 1, TRUE);
|
||||
TSTR title = GetString(IDS_TH_EDITPATCH_CLASS),
|
||||
warning = GetString(IDS_PW_SURFACEERROR);
|
||||
|
||||
MessageBox(GetCOREInterface()->GetMAXHWnd(),
|
||||
warning, title, MB_OK | MB_APPLMODAL);
|
||||
}
|
||||
|
||||
if (i >= inPatch.numVerts)
|
||||
outPatch.verts[pv.vert].p = zeroPoint;
|
||||
else
|
||||
outPatch.verts[pv.vert].p = pv.original + pv.delta;
|
||||
#ifdef VMAP_DEBUG
|
||||
if (pv.delta != zeroPoint)
|
||||
DebugPrint("Vert %d applied delta of %.2f %.2f %.2f\n", i, pv.delta.x, pv.delta.y, pv.delta.z);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
for (i = 0; i < vecs; ++i)
|
||||
{
|
||||
EPMapVert &pv = vecMap[i];
|
||||
if (pv.vert >= 0 && pv.originalStored)
|
||||
{
|
||||
// nlassert(pv.vert >= 0 && pv.vert < outPatch.numVecs);
|
||||
// watje 4-27-99 instead just throwing an nlassert it pops a message box up and troes to recover
|
||||
if (!(pv.vert >= 0 && pv.vert < outPatch.numVecs))
|
||||
{
|
||||
outPatch.setNumVecs(pv.vert + 1, TRUE);
|
||||
|
||||
TSTR title = GetString(IDS_TH_EDITPATCH_CLASS),
|
||||
warning = GetString(IDS_PW_SURFACEERROR);
|
||||
|
||||
MessageBox(GetCOREInterface()->GetMAXHWnd(),
|
||||
warning, title, MB_OK | MB_APPLMODAL);
|
||||
}
|
||||
|
||||
if (i >= inPatch.numVecs)
|
||||
outPatch.vecs[pv.vert].p = zeroPoint;
|
||||
else
|
||||
outPatch.vecs[pv.vert].p = pv.original + pv.delta;
|
||||
#ifdef VMAP_DEBUG
|
||||
if (pv.delta != zeroPoint)
|
||||
DebugPrint("Vec %d applied delta of %.2f %.2f %.2f\n", i, pv.delta.x, pv.delta.y, pv.delta.z);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EPVertMapper& EPVertMapper::operator=(EPVertMapper &from)
|
||||
{
|
||||
if (vertMap)
|
||||
delete[] vertMap;
|
||||
verts = from.verts;
|
||||
vertMap = new EPMapVert[verts];
|
||||
int i;
|
||||
for (i = 0; i < verts; ++i)
|
||||
vertMap[i] = from.vertMap[i];
|
||||
if (vecMap)
|
||||
delete[] vecMap;
|
||||
vecs = from.vecs;
|
||||
vecMap = new EPMapVert[vecs];
|
||||
for (i = 0; i < vecs; ++i)
|
||||
vecMap[i] = from.vecMap[i];
|
||||
return *this;
|
||||
}
|
||||
|
||||
void EPVertMapper::RescaleWorldUnits(float f)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < verts; ++i)
|
||||
{
|
||||
vertMap[i].delta *= f;
|
||||
if (vertMap[i].originalStored)
|
||||
vertMap[i].original *= f;
|
||||
}
|
||||
for (i = 0; i < vecs; ++i)
|
||||
{
|
||||
vecMap[i].delta *= f;
|
||||
if (vecMap[i].originalStored)
|
||||
vecMap[i].original *= f;
|
||||
}
|
||||
}
|
||||
|
||||
#define EPVM_DATA_CHUNK 0x1000
|
||||
|
||||
IOResult EPVertMapper::Save(ISave *isave)
|
||||
{
|
||||
ULONG nb;
|
||||
isave->BeginChunk(EPVM_DATA_CHUNK);
|
||||
isave->Write(&verts, sizeof(int), &nb);
|
||||
isave->Write(vertMap, sizeof(EPMapVert) * verts, &nb);
|
||||
isave->Write(&vecs, sizeof(int), &nb);
|
||||
isave->Write(vecMap, sizeof(EPMapVert) * vecs, &nb);
|
||||
isave->EndChunk();
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
IOResult EPVertMapper::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
ULONG nb;
|
||||
int index = 0;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case EPVM_DATA_CHUNK:
|
||||
res = iload->Read(&verts, sizeof(int), &nb);
|
||||
if (vertMap)
|
||||
delete[] vertMap;
|
||||
vertMap = new EPMapVert[verts];
|
||||
res = iload->Read(vertMap, sizeof(EPMapVert) * verts, &nb);
|
||||
res = iload->Read(&vecs, sizeof(int), &nb);
|
||||
if (vecMap)
|
||||
delete[] vecMap;
|
||||
vecMap = new EPMapVert[vecs];
|
||||
res = iload->Read(vecMap, sizeof(EPMapVert) * vecs, &nb);
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
|
@ -1,714 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
#include "nel/misc/time_nl.h"
|
||||
|
||||
using namespace NLMISC;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
class EPVertMapRestore : public RestoreObj
|
||||
{
|
||||
public:
|
||||
BOOL gotRedo;
|
||||
EPVertMapper undo;
|
||||
EPVertMapper redo;
|
||||
EditPatchData *epd;
|
||||
|
||||
EPVertMapRestore(EditPatchData *d)
|
||||
{
|
||||
undo = d->vertMap;
|
||||
epd = d;
|
||||
gotRedo = FALSE;
|
||||
}
|
||||
|
||||
void Restore(int isUndo)
|
||||
{
|
||||
if (!gotRedo)
|
||||
{
|
||||
gotRedo = TRUE;
|
||||
redo = epd->vertMap;
|
||||
}
|
||||
epd->vertMap = undo;
|
||||
}
|
||||
|
||||
void Redo()
|
||||
{
|
||||
epd->vertMap = redo;
|
||||
}
|
||||
|
||||
int Size() { return 1; }
|
||||
void EndHold() { }
|
||||
TSTR Description() { return TSTR(_T("EPVertMapRestore")); }
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
class FinalPatchRestore : public RestoreObj
|
||||
{
|
||||
public:
|
||||
BOOL gotRedo;
|
||||
PatchMesh undo;
|
||||
PatchMesh redo;
|
||||
PatchMesh *patch;
|
||||
RPatchMesh *rundo;
|
||||
RPatchMesh *rredo;
|
||||
RPatchMesh *rpatch;
|
||||
|
||||
FinalPatchRestore(PatchMesh *s, RPatchMesh *rs)
|
||||
{
|
||||
rundo = NULL;
|
||||
rredo = NULL;
|
||||
|
||||
undo = *s;
|
||||
|
||||
if (rs)
|
||||
{
|
||||
rundo=new RPatchMesh();
|
||||
*rundo = *rs;
|
||||
}
|
||||
|
||||
patch = s;
|
||||
rpatch = rs;
|
||||
gotRedo = FALSE;
|
||||
}
|
||||
|
||||
virtual ~FinalPatchRestore()
|
||||
{
|
||||
if (rundo)
|
||||
delete rundo;
|
||||
if (rredo)
|
||||
delete rredo;
|
||||
}
|
||||
|
||||
void Restore(int isUndo)
|
||||
{
|
||||
if (!gotRedo)
|
||||
{
|
||||
gotRedo = TRUE;
|
||||
redo = *patch;
|
||||
|
||||
if (rpatch)
|
||||
{
|
||||
if (rredo==NULL)
|
||||
rredo=new RPatchMesh();
|
||||
|
||||
*rredo = *rpatch;
|
||||
}
|
||||
}
|
||||
*patch = undo;
|
||||
|
||||
if (rundo)
|
||||
*rpatch = *rundo;
|
||||
}
|
||||
|
||||
void Redo()
|
||||
{
|
||||
*patch = redo;
|
||||
|
||||
if (rredo)
|
||||
*rpatch = *rredo;
|
||||
}
|
||||
|
||||
int Size() { return 1; }
|
||||
void EndHold() { }
|
||||
TSTR Description() { return TSTR(_T("FinalPatchRestore")); }
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
EditPatchData::EditPatchData(EditPatchMod *mod)
|
||||
{
|
||||
meshSteps = mod->meshSteps;
|
||||
// 3-18-99 to suport render steps and removal of the mental tesselator
|
||||
meshStepsRender = mod->meshStepsRender;
|
||||
showInterior = mod->showInterior;
|
||||
|
||||
// meshAdaptive = mod->meshAdaptive; // Future use (Not used now)
|
||||
viewTess = mod->viewTess;
|
||||
prodTess = mod->prodTess;
|
||||
dispTess = mod->dispTess;
|
||||
tileLevel = mod->tileLevel;
|
||||
tileMode = mod->tileMode;
|
||||
includeMeshes = mod->includeMeshes;
|
||||
transitionType = mod->transitionType;
|
||||
keepMapping = mod->keepMapping;
|
||||
mViewTessNormals = mod->mViewTessNormals;
|
||||
mProdTessNormals = mod->mProdTessNormals;
|
||||
mViewTessWeld = mod->mViewTessWeld;
|
||||
mProdTessWeld = mod->mProdTessWeld;
|
||||
displayLattice = mod->displayLattice;
|
||||
displaySurface = mod->displaySurface;
|
||||
flags = 0;
|
||||
tempData = NULL;
|
||||
}
|
||||
|
||||
EditPatchData::EditPatchData(EditPatchData& emc)
|
||||
{
|
||||
meshSteps = emc.meshSteps;
|
||||
// 3-18-99 to suport render steps and removal of the mental tesselator
|
||||
meshStepsRender = emc.meshStepsRender;
|
||||
showInterior = emc.showInterior;
|
||||
|
||||
// meshAdaptive = emc.meshAdaptive; // Future use (Not used now)
|
||||
viewTess = emc.viewTess;
|
||||
prodTess = emc.prodTess;
|
||||
dispTess = emc.dispTess;
|
||||
tileLevel = emc.tileLevel;
|
||||
transitionType = emc.transitionType;
|
||||
tileMode = emc.tileMode;
|
||||
includeMeshes = emc.includeMeshes;
|
||||
keepMapping = emc.keepMapping;
|
||||
mViewTessNormals = emc.mViewTessNormals;
|
||||
mProdTessNormals = emc.mProdTessNormals;
|
||||
mViewTessWeld = emc.mViewTessWeld;
|
||||
mProdTessWeld = emc.mProdTessWeld;
|
||||
displayLattice = emc.displayLattice;
|
||||
displaySurface = emc.displaySurface;
|
||||
flags = emc.flags;
|
||||
tempData = NULL;
|
||||
vertMap = emc.vertMap;
|
||||
finalPatch = emc.finalPatch;
|
||||
rfinalPatch = emc.rfinalPatch;
|
||||
}
|
||||
|
||||
void EditPatchData::Apply(TimeValue t, RPO *patchOb, int selLevel)
|
||||
{
|
||||
TTicks ticks=CTime::getPerformanceTime ();
|
||||
// Either just copy it from the existing cache or rebuild from previous level!
|
||||
if (!GetFlag(EPD_UPDATING_CACHE) && tempData
|
||||
&& tempData->PatchCached(t))
|
||||
{
|
||||
RPatchMesh *rpatch;
|
||||
PatchMesh *patch=tempData->GetPatch(t, rpatch);
|
||||
patchOb->patch.DeepCopy( patch,
|
||||
PART_GEOM | SELECT_CHANNEL | PART_SUBSEL_TYPE|
|
||||
PART_DISPLAY | PART_TOPO | TEXMAP_CHANNEL);
|
||||
//rpatch->UpdateBinding (*patch, t);
|
||||
*patchOb->rpatch=*rpatch;
|
||||
patchOb->PointsWereChanged();
|
||||
}
|
||||
else if (GetFlag(EPD_HASDATA))
|
||||
{
|
||||
// For old files, which contain exhaustive data to reconstruct the editing process
|
||||
// of patches, we'll have data in the 'changes' table. If it's there, go ahead and
|
||||
// replay the edits, then store the alterations in our new delta format and discard
|
||||
// the change table!
|
||||
int count = changes.Count();
|
||||
if (count)
|
||||
{
|
||||
// DebugPrint("*** Applying old style (%d) ***\n", count);
|
||||
// Store the topology for future reference
|
||||
vertMap.Build(patchOb->patch);
|
||||
finalPatch = patchOb->patch;
|
||||
rfinalPatch = *patchOb->rpatch;
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
PModRecord *rec = changes[i];
|
||||
// Record the topo flags
|
||||
RecordTopologyTags(&patchOb->patch);
|
||||
BOOL result = rec->Redo(&patchOb->patch, patchOb->rpatch, 0);
|
||||
UpdateChanges(&patchOb->patch, patchOb->rpatch);
|
||||
// If we hit one that didn't play back OK, we need to flush the remainder
|
||||
if (!result)
|
||||
{
|
||||
for (int j = i; j < count; ++j)
|
||||
delete changes[j];
|
||||
changes.Delete(i, count - i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Nuke the changes table
|
||||
count = changes.Count();
|
||||
for (int k = 0; k < count; ++k)
|
||||
delete changes[k];
|
||||
changes.Delete(0, count);
|
||||
changes.Shrink();
|
||||
count = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Apply deltas to incoming shape, placing into finalPatch
|
||||
vertMap.UpdateAndApplyDeltas(patchOb->patch, finalPatch);
|
||||
patchOb->patch = finalPatch;
|
||||
*patchOb->rpatch = rfinalPatch;
|
||||
}
|
||||
patchOb->PointsWereChanged();
|
||||
// Kind of a waste when there's no animation...
|
||||
patchOb->UpdateValidity(GEOM_CHAN_NUM, FOREVER);
|
||||
patchOb->UpdateValidity(TOPO_CHAN_NUM, FOREVER);
|
||||
patchOb->UpdateValidity(SELECT_CHAN_NUM, FOREVER);
|
||||
patchOb->UpdateValidity(SUBSEL_TYPE_CHAN_NUM, FOREVER);
|
||||
patchOb->UpdateValidity(DISP_ATTRIB_CHAN_NUM, FOREVER);
|
||||
}
|
||||
else
|
||||
{ // No data yet -- Store initial required data
|
||||
// DebugPrint("<<<Storing Initial Data>>>\n");
|
||||
vertMap.Build(patchOb->patch);
|
||||
finalPatch = patchOb->patch;
|
||||
rfinalPatch = *patchOb->rpatch;
|
||||
}
|
||||
|
||||
// Hand it its mesh interpolation info
|
||||
patchOb->SetMeshSteps(meshSteps);
|
||||
// 3-18-99 to suport render steps and removal of the mental tesselator
|
||||
patchOb->SetMeshStepsRender(meshStepsRender);
|
||||
patchOb->SetShowInterior(showInterior);
|
||||
|
||||
// patchOb->SetAdaptive(meshAdaptive); // Future use (Not used now)
|
||||
patchOb->SetViewTess(viewTess);
|
||||
patchOb->SetProdTess(prodTess);
|
||||
patchOb->SetDispTess(dispTess);
|
||||
patchOb->rpatch->rTess.ModeTile=tileMode;
|
||||
patchOb->rpatch->rTess.TileTesselLevel=tileLevel;
|
||||
patchOb->rpatch->rTess.TransitionType=transitionType;
|
||||
patchOb->rpatch->rTess.KeepMapping=keepMapping;
|
||||
patchOb->SetViewTessNormals(mViewTessNormals);
|
||||
patchOb->SetProdTessNormals(mProdTessNormals);
|
||||
patchOb->SetViewTessWeld(mViewTessWeld);
|
||||
patchOb->SetProdTessWeld(mProdTessWeld);
|
||||
|
||||
patchOb->showMesh = displaySurface;
|
||||
patchOb->SetShowLattice(displayLattice);
|
||||
patchOb->patch.dispFlags = 0; // TH 3/3/99
|
||||
switch (selLevel)
|
||||
{
|
||||
case EP_PATCH:
|
||||
patchOb->patch.SetDispFlag(DISP_SELPATCHES);
|
||||
break;
|
||||
case EP_EDGE:
|
||||
patchOb->patch.SetDispFlag(DISP_SELEDGES);
|
||||
break;
|
||||
case EP_VERTEX:
|
||||
patchOb->patch.SetDispFlag(DISP_VERTTICKS | DISP_SELVERTS | DISP_VERTS);
|
||||
break;
|
||||
case EP_TILE:
|
||||
//patchOb->patch.SetDispFlag(DISP_VERTTICKS | DISP_SELVERTS | DISP_VERTS);
|
||||
break;
|
||||
}
|
||||
patchOb->patch.selLevel = patchLevel[selLevel];
|
||||
patchOb->rpatch->SetSelLevel (selLevel);
|
||||
|
||||
/*rfinalPatch.UpdateBinding (finalPatch, t);
|
||||
patchOb->rpatch->UpdateBinding (patchOb->patch, t);*/
|
||||
|
||||
if (GetFlag(EPD_UPDATING_CACHE))
|
||||
{
|
||||
nlassert(tempData);
|
||||
tempData->UpdateCache(patchOb);
|
||||
SetFlag(EPD_UPDATING_CACHE, FALSE);
|
||||
}
|
||||
ticks=CTime::getPerformanceTime ()-ticks;
|
||||
nldebug ("%f", CTime::ticksToSecond(ticks));
|
||||
}
|
||||
|
||||
void EditPatchData::Invalidate(PartID part, BOOL patchValid)
|
||||
{
|
||||
if (tempData)
|
||||
{
|
||||
tempData->Invalidate(part, patchValid);
|
||||
}
|
||||
}
|
||||
|
||||
void EditPatchData::BeginEdit(TimeValue t)
|
||||
{
|
||||
nlassert(tempData);
|
||||
if (!GetFlag(EPD_HASDATA))
|
||||
SetFlag(EPD_HASDATA, TRUE);
|
||||
}
|
||||
|
||||
EPTempData *EditPatchData::TempData(EditPatchMod *mod)
|
||||
{
|
||||
if (!tempData)
|
||||
{
|
||||
nlassert(mod->ip);
|
||||
tempData = new EPTempData(mod, this);
|
||||
}
|
||||
return tempData;
|
||||
}
|
||||
|
||||
void EditPatchData::RescaleWorldUnits(float f)
|
||||
{
|
||||
// Scale the deltas inside the vertex map
|
||||
vertMap.RescaleWorldUnits(f);
|
||||
// Now rescale stuff inside our data structures
|
||||
Matrix3 stm = ScaleMatrix(Point3(f, f, f));
|
||||
finalPatch.Transform(stm);
|
||||
}
|
||||
|
||||
void EditPatchData::RecordTopologyTags(PatchMesh *patch)
|
||||
{
|
||||
// First, stuff all -1's into aux fields
|
||||
int i;
|
||||
for (i = 0; i < patch->numVerts; ++i)
|
||||
patch->verts[i].aux1 = 0xffffffff;
|
||||
for (i = 0; i < patch->numVecs; ++i)
|
||||
patch->vecs[i].aux1 = 0xffffffff;
|
||||
for (i = 0; i < patch->numPatches; ++i)
|
||||
patch->patches[i].aux1 = 0xffffffff;
|
||||
// Now put in our tags
|
||||
vertMap.RecordTopologyTags(*patch);
|
||||
}
|
||||
|
||||
GenericNamedSelSetList &EditPatchData::GetSelSet(EditPatchMod *mod)
|
||||
{
|
||||
switch (mod->GetSubobjectLevel())
|
||||
{
|
||||
case EP_VERTEX:
|
||||
return vselSet;
|
||||
case EP_EDGE:
|
||||
return eselSet;
|
||||
case EP_PATCH:
|
||||
case EP_TILE:
|
||||
default:
|
||||
return pselSet;
|
||||
}
|
||||
}
|
||||
|
||||
GenericNamedSelSetList &EditPatchData::GetSelSet(int level)
|
||||
{
|
||||
switch (level + EP_VERTEX)
|
||||
{
|
||||
case EP_VERTEX:
|
||||
return vselSet;
|
||||
case EP_EDGE:
|
||||
return eselSet;
|
||||
case EP_PATCH:
|
||||
case EP_TILE:
|
||||
default:
|
||||
return pselSet;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EditPatchData::UpdateChanges(PatchMesh *patch, RPatchMesh *rpatch, BOOL checkTopology)
|
||||
{
|
||||
if (theHold.Holding())
|
||||
{
|
||||
theHold.Put(new EPVertMapRestore(this));
|
||||
//theHold.Put(new FinalPatchRestore(&finalPatch, &rfinalPatch));
|
||||
if (rpatch)
|
||||
theHold.Put(new FinalPatchRestore(&finalPatch, &rfinalPatch));
|
||||
else
|
||||
theHold.Put(new FinalPatchRestore(&finalPatch, NULL));
|
||||
}
|
||||
// Update the mapper's indices
|
||||
if (checkTopology)
|
||||
vertMap.UpdateMapping(*patch);
|
||||
// Update mapper's XYZ deltas
|
||||
vertMap.RecomputeDeltas(*patch);
|
||||
// Store the final shape
|
||||
finalPatch = *patch;
|
||||
|
||||
if (rpatch)
|
||||
rfinalPatch = *rpatch;
|
||||
}
|
||||
|
||||
#define EPD_GENERAL_CHUNK 0x1000 // Obsolete as of 11/12/98 (r3)
|
||||
#define CHANGE_CHUNK 0x1010 // Obsolete as of 11/12/98 (r3)
|
||||
#define EPD_R3_GENERAL_CHUNK 0x1015
|
||||
#define MESH_ATTRIB_CHUNK 0x1020
|
||||
#define DISP_PARTS_CHUNK 0x1030
|
||||
#define VTESS_ATTRIB_CHUNK 0x1070
|
||||
#define PTESS_ATTRIB_CHUNK 0x1080
|
||||
#define DTESS_ATTRIB_CHUNK 0x1090
|
||||
#define NORMAL_TESS_ATTRIB_CHUNK 0x1110
|
||||
#define WELD_TESS_ATTRIB_CHUNK 0x1120
|
||||
#define VERTMAP_CHUNK 0x1130
|
||||
#define FINALPATCH_CHUNK 0x1140
|
||||
#define RENDERSTEPS_CHUNK 0x1150
|
||||
#define SHOWINTERIOR_CHUNK 0x1160
|
||||
|
||||
// Named sel set chunks
|
||||
#define VSELSET_CHUNK 0x1040
|
||||
#define ESELSET_CHUNK 0x1050
|
||||
#define PSELSET_CHUNK 0x1060
|
||||
|
||||
#define RPO_MODE_TILE 0x4000
|
||||
#define RFINALPATCH_CHUNK 0x4001
|
||||
#define RPO_MODE_TILE_TRANSITION 0x4002
|
||||
#define RPO_INCLUDE_MESHES 0x4003
|
||||
|
||||
IOResult EditPatchData::Save(ISave *isave)
|
||||
{
|
||||
ULONG nb;
|
||||
isave->BeginChunk(EPD_R3_GENERAL_CHUNK);
|
||||
isave->Write(&flags, sizeof(DWORD), &nb);
|
||||
isave->EndChunk();
|
||||
isave->BeginChunk(MESH_ATTRIB_CHUNK);
|
||||
isave->Write(&meshSteps, sizeof(int), &nb);
|
||||
// Future use (Not used now)
|
||||
BOOL fakeAdaptive = FALSE;
|
||||
isave->Write(&fakeAdaptive, sizeof(BOOL), &nb);
|
||||
// isave->Write(&meshAdaptive,sizeof(BOOL),&nb); // Future use (Not used now)
|
||||
isave->EndChunk();
|
||||
|
||||
// 3-18-99 to suport render steps and removal of the mental tesselator
|
||||
isave->BeginChunk(RENDERSTEPS_CHUNK);
|
||||
if ((meshStepsRender < 0) ||(meshStepsRender > 100))
|
||||
{
|
||||
meshStepsRender = 5;
|
||||
nlassert(0);
|
||||
}
|
||||
isave->Write(&meshStepsRender, sizeof(int), &nb);
|
||||
isave->EndChunk();
|
||||
isave->BeginChunk(SHOWINTERIOR_CHUNK);
|
||||
isave->Write(&showInterior, sizeof(BOOL), &nb);
|
||||
isave->EndChunk();
|
||||
|
||||
|
||||
isave->BeginChunk(VTESS_ATTRIB_CHUNK);
|
||||
viewTess.Save(isave);
|
||||
isave->EndChunk();
|
||||
isave->BeginChunk(PTESS_ATTRIB_CHUNK);
|
||||
prodTess.Save(isave);
|
||||
isave->EndChunk();
|
||||
isave->BeginChunk(DTESS_ATTRIB_CHUNK);
|
||||
dispTess.Save(isave);
|
||||
isave->EndChunk();
|
||||
isave->BeginChunk(DISP_PARTS_CHUNK);
|
||||
isave->Write(&displaySurface, sizeof(BOOL), &nb);
|
||||
isave->Write(&displayLattice, sizeof(BOOL), &nb);
|
||||
isave->EndChunk();
|
||||
|
||||
isave->BeginChunk(NORMAL_TESS_ATTRIB_CHUNK);
|
||||
isave->Write(&mViewTessNormals, sizeof(BOOL), &nb);
|
||||
isave->Write(&mProdTessNormals, sizeof(BOOL), &nb);
|
||||
isave->EndChunk();
|
||||
|
||||
isave->BeginChunk(WELD_TESS_ATTRIB_CHUNK);
|
||||
isave->Write(&mViewTessWeld, sizeof(BOOL), &nb);
|
||||
isave->Write(&mProdTessWeld, sizeof(BOOL), &nb);
|
||||
isave->EndChunk();
|
||||
|
||||
isave->BeginChunk(RPO_MODE_TILE);
|
||||
isave->Write(&tileMode, sizeof(tileMode), &nb);
|
||||
isave->Write(&tileLevel, sizeof(tileLevel), &nb);
|
||||
isave->Write(&keepMapping, sizeof(keepMapping), &nb);
|
||||
isave->EndChunk();
|
||||
|
||||
isave->BeginChunk(RPO_INCLUDE_MESHES);
|
||||
isave->Write(&includeMeshes, sizeof(includeMeshes), &nb);
|
||||
isave->EndChunk();
|
||||
|
||||
isave->BeginChunk(RPO_MODE_TILE_TRANSITION);
|
||||
isave->Write(&transitionType, sizeof(transitionType), &nb);
|
||||
isave->EndChunk();
|
||||
|
||||
// Save named sel sets
|
||||
if (vselSet.Count())
|
||||
{
|
||||
isave->BeginChunk(VSELSET_CHUNK);
|
||||
vselSet.Save(isave);
|
||||
isave->EndChunk();
|
||||
}
|
||||
if (eselSet.Count())
|
||||
{
|
||||
isave->BeginChunk(ESELSET_CHUNK);
|
||||
eselSet.Save(isave);
|
||||
isave->EndChunk();
|
||||
}
|
||||
if (pselSet.Count())
|
||||
{
|
||||
isave->BeginChunk(PSELSET_CHUNK);
|
||||
pselSet.Save(isave);
|
||||
isave->EndChunk();
|
||||
}
|
||||
|
||||
isave->BeginChunk(VERTMAP_CHUNK);
|
||||
vertMap.Save(isave);
|
||||
isave->EndChunk();
|
||||
isave->BeginChunk(FINALPATCH_CHUNK);
|
||||
finalPatch.Save(isave);
|
||||
isave->EndChunk();
|
||||
|
||||
isave->BeginChunk(RFINALPATCH_CHUNK);
|
||||
rfinalPatch.Save(isave);
|
||||
isave->EndChunk();
|
||||
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
IOResult EditPatchData::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
ULONG nb;
|
||||
PModRecord *theChange;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
// The following code is here to load pre-release 3 files.
|
||||
case EPD_GENERAL_CHUNK:
|
||||
iload->SetObsolete();
|
||||
iload->Read(&flags, sizeof(DWORD), &nb);
|
||||
break;
|
||||
case CLEARVERTSELRECORD_CHUNK:
|
||||
theChange = new ClearPVertSelRecord;
|
||||
goto load_change;
|
||||
case SETVERTSELRECORD_CHUNK:
|
||||
theChange = new SetPVertSelRecord;
|
||||
goto load_change;
|
||||
case INVERTVERTSELRECORD_CHUNK:
|
||||
theChange = new InvertPVertSelRecord;
|
||||
goto load_change;
|
||||
case CLEAREDGESELRECORD_CHUNK:
|
||||
theChange = new ClearPEdgeSelRecord;
|
||||
goto load_change;
|
||||
case SETEDGESELRECORD_CHUNK:
|
||||
theChange = new SetPEdgeSelRecord;
|
||||
goto load_change;
|
||||
case INVERTEDGESELRECORD_CHUNK:
|
||||
theChange = new InvertPEdgeSelRecord;
|
||||
goto load_change;
|
||||
case CLEARPATCHSELRECORD_CHUNK:
|
||||
theChange = new ClearPatchSelRecord;
|
||||
goto load_change;
|
||||
case SETPATCHSELRECORD_CHUNK:
|
||||
theChange = new SetPatchSelRecord;
|
||||
goto load_change;
|
||||
case INVERTPATCHSELRECORD_CHUNK:
|
||||
theChange = new InvertPatchSelRecord;
|
||||
goto load_change;
|
||||
case VERTSELRECORD_CHUNK:
|
||||
theChange = new PVertSelRecord;
|
||||
goto load_change;
|
||||
case EDGESELRECORD_CHUNK:
|
||||
theChange = new PEdgeSelRecord;
|
||||
goto load_change;
|
||||
case PATCHSELRECORD_CHUNK:
|
||||
theChange = new PatchSelRecord;
|
||||
goto load_change;
|
||||
case PATCHDELETERECORD_CHUNK:
|
||||
theChange = new PatchDeleteRecord;
|
||||
goto load_change;
|
||||
case VERTMOVERECORD_CHUNK:
|
||||
theChange = new PVertMoveRecord;
|
||||
goto load_change;
|
||||
case PATCHCHANGERECORD_CHUNK:
|
||||
theChange = new PatchChangeRecord;
|
||||
goto load_change;
|
||||
case VERTCHANGERECORD_CHUNK:
|
||||
theChange = new PVertChangeRecord;
|
||||
goto load_change;
|
||||
case PATCHADDRECORD_CHUNK:
|
||||
theChange = new PatchAddRecord;
|
||||
goto load_change;
|
||||
case EDGESUBDIVIDERECORD_CHUNK:
|
||||
theChange = new EdgeSubdivideRecord;
|
||||
goto load_change;
|
||||
case PATCHSUBDIVIDERECORD_CHUNK:
|
||||
theChange = new PatchSubdivideRecord;
|
||||
goto load_change;
|
||||
case PATTACHRECORD_CHUNK:
|
||||
theChange = new PAttachRecord;
|
||||
goto load_change;
|
||||
case PATCHDETACHRECORD_CHUNK:
|
||||
theChange = new PatchDetachRecord;
|
||||
goto load_change;
|
||||
case PATCHMTLRECORD_CHUNK:
|
||||
theChange = new PatchMtlRecord;
|
||||
goto load_change;
|
||||
case VERTWELDRECORD_CHUNK:
|
||||
theChange = new PVertWeldRecord;
|
||||
goto load_change;
|
||||
case VERTDELETERECORD_CHUNK:
|
||||
theChange = new PVertDeleteRecord;
|
||||
// Intentional fall-thru!
|
||||
load_change:
|
||||
changes.Append(1, &theChange);
|
||||
changes[changes.Count() - 1]->Load(iload);
|
||||
break;
|
||||
//
|
||||
// The following code is used for post-release 3 files
|
||||
//
|
||||
case EPD_R3_GENERAL_CHUNK:
|
||||
res = iload->Read(&flags, sizeof(DWORD), &nb);
|
||||
break;
|
||||
case VERTMAP_CHUNK:
|
||||
res = vertMap.Load(iload);
|
||||
break;
|
||||
case FINALPATCH_CHUNK:
|
||||
res = finalPatch.Load(iload);
|
||||
break;
|
||||
case RFINALPATCH_CHUNK:
|
||||
res = rfinalPatch.Load(iload);
|
||||
break;
|
||||
//
|
||||
// The following code is common to all versions' files
|
||||
//
|
||||
case MESH_ATTRIB_CHUNK:
|
||||
iload->Read(&meshSteps, sizeof(int), &nb);
|
||||
res = iload->Read(&meshAdaptive, sizeof(BOOL), &nb); // Future use (Not used now)
|
||||
break;
|
||||
// 3-18-99 to suport render steps and removal of the mental tesselator
|
||||
case RENDERSTEPS_CHUNK:
|
||||
iload->Read(&meshStepsRender, sizeof(int), &nb);
|
||||
if ((meshStepsRender < 0) ||(meshStepsRender > 100))
|
||||
{
|
||||
meshStepsRender = 5;
|
||||
nlassert(0);
|
||||
}
|
||||
|
||||
break;
|
||||
case SHOWINTERIOR_CHUNK:
|
||||
iload->Read(&showInterior, sizeof(BOOL), &nb);
|
||||
break;
|
||||
|
||||
case VTESS_ATTRIB_CHUNK:
|
||||
viewTess.Load(iload);
|
||||
break;
|
||||
case PTESS_ATTRIB_CHUNK:
|
||||
prodTess.Load(iload);
|
||||
break;
|
||||
case DTESS_ATTRIB_CHUNK:
|
||||
dispTess.Load(iload);
|
||||
break;
|
||||
case NORMAL_TESS_ATTRIB_CHUNK:
|
||||
iload->Read(&mViewTessNormals, sizeof(BOOL), &nb);
|
||||
res = iload->Read(&mProdTessNormals, sizeof(BOOL), &nb);
|
||||
break;
|
||||
case WELD_TESS_ATTRIB_CHUNK:
|
||||
iload->Read(&mViewTessWeld, sizeof(BOOL), &nb);
|
||||
res = iload->Read(&mProdTessWeld, sizeof(BOOL), &nb);
|
||||
break;
|
||||
case DISP_PARTS_CHUNK:
|
||||
iload->Read(&displaySurface, sizeof(BOOL), &nb);
|
||||
res = iload->Read(&displayLattice, sizeof(BOOL), &nb);
|
||||
break;
|
||||
// Load named selection sets
|
||||
case VSELSET_CHUNK:
|
||||
res = vselSet.Load(iload);
|
||||
break;
|
||||
case PSELSET_CHUNK:
|
||||
res = pselSet.Load(iload);
|
||||
break;
|
||||
case ESELSET_CHUNK:
|
||||
res = eselSet.Load(iload);
|
||||
break;
|
||||
|
||||
case RPO_MODE_TILE:
|
||||
res = iload->Read(&tileMode, sizeof(tileMode), &nb);
|
||||
res = iload->Read(&tileLevel, sizeof(tileLevel), &nb);
|
||||
res = iload->Read(&keepMapping, sizeof(keepMapping), &nb);
|
||||
break;
|
||||
|
||||
case RPO_INCLUDE_MESHES:
|
||||
res = iload->Read(&includeMeshes, sizeof(includeMeshes), &nb);
|
||||
break;
|
||||
|
||||
case RPO_MODE_TILE_TRANSITION:
|
||||
res = iload->Read(&transitionType, sizeof(transitionType), &nb);
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
@ -1,311 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
void EPM_BindCMode::EnterMode()
|
||||
{
|
||||
if (pobj->hOpsPanel)
|
||||
{
|
||||
ICustButton *but = GetICustButton(GetDlgItem(pobj->hOpsPanel, IDC_BIND));
|
||||
but->SetCheck(TRUE);
|
||||
ReleaseICustButton(but);
|
||||
}
|
||||
}
|
||||
|
||||
void EPM_BindCMode::ExitMode()
|
||||
{
|
||||
if (pobj->hOpsPanel)
|
||||
{
|
||||
ICustButton *but = GetICustButton(GetDlgItem(pobj->hOpsPanel, IDC_BIND));
|
||||
but->SetCheck(FALSE);
|
||||
ReleaseICustButton(but);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
|
||||
HCURSOR EPM_BindMouseProc::GetTransformCursor()
|
||||
{
|
||||
static HCURSOR hCur = NULL;
|
||||
|
||||
if (!hCur)
|
||||
{
|
||||
hCur = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_SEGREFINECUR));
|
||||
}
|
||||
|
||||
return hCur;
|
||||
}
|
||||
|
||||
BOOL EPM_BindMouseProc::HitTest(
|
||||
ViewExp *vpt, IPoint2 *p, int type, int flags, int subType)
|
||||
{
|
||||
vpt->ClearSubObjHitList();
|
||||
SetPatchHitOverride(subType);
|
||||
|
||||
ip->SubObHitTest(ip->GetTime(), type, ip->GetCrossing(), flags, p, vpt);
|
||||
ClearPatchHitOverride();
|
||||
if (vpt->NumSubObjHits())
|
||||
{
|
||||
return TRUE;
|
||||
} else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL EPM_BindMouseProc::HitAKnot(ViewExp *vpt, IPoint2 *p, int *vert)
|
||||
{
|
||||
int first = 1;
|
||||
|
||||
if (HitTest(vpt, p, HITTYPE_POINT, 0, 1))
|
||||
{
|
||||
HitLog &hits = vpt->GetSubObjHitList();
|
||||
HitRecord *rec = hits.First();
|
||||
DWORD best = 9999;
|
||||
HitRecord *bestRec;
|
||||
while (rec)
|
||||
{
|
||||
PatchHitData *hit =((PatchHitData *)rec->hitData);
|
||||
// If there's an exclusion shape, this must be a part of it!
|
||||
pMesh = hit->patch;
|
||||
|
||||
if (1)
|
||||
{
|
||||
if (hit->type == PATCH_HIT_VERTEX)
|
||||
{
|
||||
|
||||
// If there's an exclusion shape, the vert & poly can't be the same!
|
||||
if (first || rec->distance < best)
|
||||
{
|
||||
first = 0;
|
||||
best = rec->distance;
|
||||
bestRec = rec;
|
||||
}
|
||||
}
|
||||
}
|
||||
rec = rec->Next();
|
||||
}
|
||||
if (!first)
|
||||
{
|
||||
PatchHitData *hit =((PatchHitData *)bestRec->hitData);
|
||||
*vert = hit->index;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOL EPM_BindMouseProc::HitASegment(ViewExp *vpt, IPoint2 *p, int *seg)
|
||||
{
|
||||
int first = 1;
|
||||
|
||||
if (HitTest(vpt, p, HITTYPE_POINT, 0, 2))
|
||||
{
|
||||
HitLog &hits = vpt->GetSubObjHitList();
|
||||
HitRecord *rec = hits.First();
|
||||
DWORD best = 9999;
|
||||
HitRecord *bestRec;
|
||||
while (rec)
|
||||
{
|
||||
PatchHitData *hit =((PatchHitData *)rec->hitData);
|
||||
// If there's an exclusion shape, this must be a part of it!
|
||||
if (pMesh == hit->patch)
|
||||
{
|
||||
if (hit->type == PATCH_HIT_EDGE)
|
||||
{
|
||||
|
||||
// If there's an exclusion shape, the vert & poly can't be the same!
|
||||
if (first || rec->distance < best)
|
||||
{
|
||||
first = 0;
|
||||
best = rec->distance;
|
||||
bestRec = rec;
|
||||
}
|
||||
}
|
||||
}
|
||||
rec = rec->Next();
|
||||
}
|
||||
if (!first)
|
||||
{
|
||||
PatchHitData *hit =((PatchHitData *)bestRec->hitData);
|
||||
*seg = hit->index;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void PatchXORDottedLine(HWND hwnd, IPoint2 p0, IPoint2 p1)
|
||||
{
|
||||
HDC hdc;
|
||||
hdc = GetDC(hwnd);
|
||||
SetROP2(hdc, R2_XORPEN);
|
||||
SetBkMode(hdc, TRANSPARENT);
|
||||
SelectObject(hdc, CreatePen(PS_DOT, 0, RGB(255, 255, 255)));
|
||||
MoveToEx(hdc, p0.x, p0.y, NULL);
|
||||
LineTo(hdc, p1.x, p1.y);
|
||||
DeleteObject(SelectObject(hdc, GetStockObject(BLACK_PEN)));
|
||||
ReleaseDC(hwnd, hdc);
|
||||
}
|
||||
|
||||
|
||||
int EPM_BindMouseProc::proc(
|
||||
HWND hwnd,
|
||||
int msg,
|
||||
int point,
|
||||
int flags,
|
||||
IPoint2 m)
|
||||
{
|
||||
ViewExp *vpt = ip->GetViewport(hwnd);
|
||||
int res = TRUE;
|
||||
static PatchMesh *shape1 = NULL;
|
||||
static int poly1, vert1, seg1;
|
||||
static IPoint2 anchor, lastPoint;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case MOUSE_PROPCLICK:
|
||||
ip->SetStdCommandMode(CID_OBJMOVE);
|
||||
break;
|
||||
|
||||
case MOUSE_POINT:
|
||||
switch (point)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (HitAKnot(vpt, &m, &vert1))
|
||||
{
|
||||
//if (rpatch->UIVertex[vert1].binded)
|
||||
{
|
||||
res = TRUE;
|
||||
anchor = lastPoint = m;
|
||||
PatchXORDottedLine(hwnd, anchor, m); // Draw it!
|
||||
// get valid seg list
|
||||
/*knotList.SetSize(pMesh->numVerts);
|
||||
knotList.ClearAll();
|
||||
for (int i = 0; i < pMesh->numEdges; i++)
|
||||
{
|
||||
if (pMesh->edges[i].v1 == vert1)
|
||||
{
|
||||
knotList.Set(pMesh->edges[i].v2);
|
||||
|
||||
}
|
||||
if (pMesh->edges[i].v2 == vert1)
|
||||
{
|
||||
knotList.Set(pMesh->edges[i].v1);
|
||||
}
|
||||
}*/
|
||||
|
||||
tab.build (*pMesh);
|
||||
}
|
||||
}
|
||||
|
||||
else res = FALSE;
|
||||
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
PatchXORDottedLine(hwnd, anchor, lastPoint); // Erase it!
|
||||
// if(HitAnEndpoint(vpt, &m, shape1, poly1, vert1, NULL, &poly2, &vert2))
|
||||
// ss->DoVertConnect(vpt, shape1, poly1, vert1, poly2, vert2);
|
||||
if (HitASegment(vpt, &m, &seg1))
|
||||
{
|
||||
// if a valid segemtn change cursor
|
||||
/*int a = pMesh->edges[seg1].v1;
|
||||
int b = pMesh->edges[seg1].v2;
|
||||
if (knotList[a] && knotList[b])
|
||||
pobj->DoAddHook(pMesh, vert1, seg1);*/
|
||||
int v0, v1, v2, v3;
|
||||
switch (CheckBind (vert1, seg1, v0, v1, v2, v3, tab, *pMesh, false, true))
|
||||
{
|
||||
case 0:
|
||||
pobj->DoAddHook(pMesh, v2, vert1, v3, seg1, 0);
|
||||
break;
|
||||
case 1:
|
||||
pobj->DoAddHook(pMesh, v2, vert1, v3, seg1, 1);
|
||||
break;
|
||||
case -1:
|
||||
break;
|
||||
default:
|
||||
nlassert (0);
|
||||
}
|
||||
}
|
||||
res = FALSE;
|
||||
break;
|
||||
default:
|
||||
nlassert(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case MOUSE_MOVE:
|
||||
// Erase old dotted line
|
||||
PatchXORDottedLine(hwnd, anchor, lastPoint);
|
||||
// Draw new dotted line
|
||||
PatchXORDottedLine(hwnd, anchor, m);
|
||||
lastPoint = m;
|
||||
if (HitASegment(vpt, &m, &seg1))
|
||||
{
|
||||
// if a valid segemtn change cursor
|
||||
/*int a = pMesh->edges[seg1].v1;
|
||||
int b = pMesh->edges[seg1].v2;
|
||||
if (knotList[a] && knotList[b])
|
||||
SetCursor(LoadCursor(hInstance, MAKEINTRESOURCE(IDC_TH_SELCURSOR)));
|
||||
else SetCursor(LoadCursor(NULL, IDC_ARROW));*/
|
||||
int v0, v1, v2, v3;
|
||||
if (CheckBind (vert1, seg1, v0, v1, v2, v3, tab, *pMesh, false, true)!=-1)
|
||||
SetCursor(LoadCursor(hInstance, MAKEINTRESOURCE(IDC_TH_SELCURSOR)));
|
||||
else
|
||||
SetCursor(LoadCursor(NULL, IDC_ARROW));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCursor(LoadCursor(NULL, IDC_ARROW));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MOUSE_FREEMOVE:
|
||||
if (HitAKnot(vpt, &m, &vert1))
|
||||
{
|
||||
SetCursor(LoadCursor(hInstance, MAKEINTRESOURCE(IDC_TH_SELCURSOR)));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCursor(LoadCursor(NULL, IDC_ARROW));
|
||||
}
|
||||
/*
|
||||
if (HitTest(vpt, &m, HITTYPE_POINT, HIT_ABORTONHIT, 1))
|
||||
{
|
||||
HitLog &hits = vpt->GetSubObjHitList();
|
||||
HitRecord *rec = hits.First();
|
||||
if (rec)
|
||||
{
|
||||
SetCursor(LoadCursor(hInstance, MAKEINTRESOURCE(IDC_TH_SELCURSOR)));
|
||||
}
|
||||
}
|
||||
SetCursor(LoadCursor(NULL, IDC_ARROW));
|
||||
*/
|
||||
break;
|
||||
|
||||
case MOUSE_ABORT:
|
||||
// Erase old dotted line
|
||||
PatchXORDottedLine(hwnd, anchor, lastPoint);
|
||||
break;
|
||||
}
|
||||
|
||||
if (vpt)
|
||||
ip->ReleaseViewport(vpt);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
|
@ -1,341 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
#define PROMPT_TIME 2000
|
||||
|
||||
BOOL CALLBACK PatchSelectDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
BOOL CALLBACK PatchOpsDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
BOOL CALLBACK PatchObjSurfDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
BOOL CALLBACK PatchSurfDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
BOOL CALLBACK PatchTileDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
BOOL CALLBACK PatchEdgeDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
extern void CancelEditPatchModes(IObjParam *ip);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// This function checks the current command mode and resets it to CID_OBJMOVE if
|
||||
// it's one of our command modes
|
||||
void CancelEditPatchModes(IObjParam *ip)
|
||||
{
|
||||
switch (ip->GetCommandMode()->ID())
|
||||
{
|
||||
case CID_STDPICK:
|
||||
ip->SetStdCommandMode(CID_OBJMOVE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// This gets rid of two-step modes, like booleans. This is necessary because
|
||||
// the first step, which activates the mode button, validates the selection set.
|
||||
// If the selection set changes, the mode must be turned off because the new
|
||||
// selection set may not be valid for the mode.
|
||||
void Cancel2StepPatchModes(IObjParam *ip)
|
||||
{
|
||||
// switch(ip->GetCommandMode()->ID()) {
|
||||
// case CID_BOOLEAN:
|
||||
// ip->SetStdCommandMode( CID_OBJMOVE );
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// IPatchSelect and IPatchOps interfaces (JBW 2/2/99)
|
||||
void* EditPatchMod::GetInterface(ULONG id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case I_PATCHSELECT:
|
||||
return (IPatchSelect*)this;
|
||||
case I_PATCHSELECTDATA:
|
||||
return (IPatchSelectData*)this;
|
||||
case I_PATCHOPS:
|
||||
return (IPatchOps*)this;
|
||||
case I_SUBMTLAPI:
|
||||
return (ISubMtlAPI*)this;
|
||||
}
|
||||
return Modifier::GetInterface(id);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::StartCommandMode(patchCommandMode mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case PcmAttach:
|
||||
if (hOpsPanel != NULL)
|
||||
PostMessage(hOpsPanel, WM_COMMAND, IDC_ATTACH, 0);
|
||||
break;
|
||||
case PcmExtrude:
|
||||
if (hOpsPanel != NULL)
|
||||
PostMessage(hOpsPanel, WM_COMMAND, IDC_EP_EXTRUDE, 0);
|
||||
break;
|
||||
case PcmBevel:
|
||||
if (hOpsPanel != NULL)
|
||||
PostMessage(hOpsPanel, WM_COMMAND, IDC_EP_BEVEL, 0);
|
||||
break;
|
||||
case PcmBind:
|
||||
if (hOpsPanel != NULL)
|
||||
PostMessage(hOpsPanel, WM_COMMAND, IDC_BIND, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::ButtonOp(patchButtonOp opcode)
|
||||
{
|
||||
switch (opcode)
|
||||
{
|
||||
case PopUnbind:
|
||||
if (hOpsPanel != NULL)
|
||||
PostMessage(hOpsPanel, WM_COMMAND, IDC_UNBIND, 0);
|
||||
break;
|
||||
case PopHide:
|
||||
if (hOpsPanel != NULL)
|
||||
PostMessage(hOpsPanel, WM_COMMAND, IDC_HIDE, 0);
|
||||
break;
|
||||
case PopUnhideAll:
|
||||
if (hOpsPanel != NULL)
|
||||
PostMessage(hOpsPanel, WM_COMMAND, IDC_UNHIDE, 0);
|
||||
break;
|
||||
case PopWeld:
|
||||
if (hOpsPanel != NULL && GetSubobjectLevel() == PO_VERTEX)
|
||||
PostMessage(hOpsPanel, WM_COMMAND, IDC_WELD, 0);
|
||||
break;
|
||||
case PopDelete:
|
||||
if (hOpsPanel != NULL && GetSubobjectLevel() >= PO_VERTEX)
|
||||
PostMessage(hOpsPanel, WM_COMMAND, IDC_PATCH_DELETE, 0);
|
||||
break;
|
||||
case PopSubdivide:
|
||||
if (hOpsPanel != NULL && GetSubobjectLevel() >= PO_EDGE && GetSubobjectLevel() != PO_TILE)
|
||||
PostMessage(hOpsPanel, WM_COMMAND, IDC_SUBDIVIDE, 0);
|
||||
break;
|
||||
case PopAddTri:
|
||||
if (hOpsPanel != NULL && GetSubobjectLevel() == PO_EDGE)
|
||||
PostMessage(hOpsPanel, WM_COMMAND, IDC_ADDTRI, 0);
|
||||
break;
|
||||
case PopAddQuad:
|
||||
if (hOpsPanel != NULL && GetSubobjectLevel() == PO_EDGE)
|
||||
PostMessage(hOpsPanel, WM_COMMAND, IDC_ADDQUAD, 0);
|
||||
break;
|
||||
case PopDetach:
|
||||
if (hOpsPanel != NULL && GetSubobjectLevel() == PO_PATCH)
|
||||
PostMessage(hOpsPanel, WM_COMMAND, IDC_DETACH, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::BeginEditParams(IObjParam *ip, ULONG flags, Animatable *prev)
|
||||
{
|
||||
this->ip = ip;
|
||||
|
||||
patchUIValid = FALSE;
|
||||
CreatePatchDataTempData();
|
||||
|
||||
hSelectPanel = ip->AddRollupPage(hInstance, MAKEINTRESOURCE(IDD_EDPATCH_SELECT),
|
||||
PatchSelectDlgProc, GetString(IDS_TH_SELECTION), (LPARAM)this, rsSel ? 0 : APPENDROLL_CLOSED);
|
||||
hOpsPanel = ip->AddRollupPage(hInstance, MAKEINTRESOURCE(IDD_EDPATCH_OPS),
|
||||
PatchOpsDlgProc, GetString(IDS_TH_GEOMETRY), (LPARAM) this, rsOps ? 0 : APPENDROLL_CLOSED);
|
||||
/* watje 3 - 18 - 99
|
||||
if (selLevel == EP_OBJECT)
|
||||
{
|
||||
hSurfPanel = ip->AddRollupPage(hInstance, MAKEINTRESOURCE(IDD_EDPATCH_SURF_OBJ),
|
||||
PatchObjSurfDlgProc, GetString(IDS_TH_SURFACEPROPERTIES), (LPARAM) this, rsSurf ? 0 : APPENDROLL_CLOSED);
|
||||
}
|
||||
else
|
||||
*/
|
||||
if (selLevel == EP_PATCH)
|
||||
{
|
||||
hSurfPanel = ip->AddRollupPage(hInstance, MAKEINTRESOURCE(IDD_EDPATCH_SURF),
|
||||
PatchSurfDlgProc, GetString(IDS_TH_SURFACEPROPERTIES), (LPARAM) this, rsSurf ? 0 : APPENDROLL_CLOSED);
|
||||
}
|
||||
else
|
||||
hSurfPanel = NULL;
|
||||
|
||||
if (selLevel == EP_TILE)
|
||||
{
|
||||
hTilePanel = ip->AddRollupPage(hInstance, MAKEINTRESOURCE(IDD_EDPATCH_TILE),
|
||||
PatchTileDlgProc, "Tile Properties", (LPARAM) this, rsTile ? 0 : APPENDROLL_CLOSED);
|
||||
}
|
||||
else
|
||||
hTilePanel = NULL;
|
||||
|
||||
if (selLevel == EP_EDGE)
|
||||
{
|
||||
hEdgePanel = ip->AddRollupPage(hInstance, MAKEINTRESOURCE(IDD_EDPATCH_EDGE),
|
||||
PatchEdgeDlgProc, "Edge Properties", (LPARAM) this, rsEdge ? 0 : APPENDROLL_CLOSED);
|
||||
}
|
||||
else
|
||||
hEdgePanel = NULL;
|
||||
|
||||
// Create sub object editing modes.
|
||||
moveMode = new MoveModBoxCMode(this, ip);
|
||||
rotMode = new RotateModBoxCMode(this, ip);
|
||||
uscaleMode = new UScaleModBoxCMode(this, ip);
|
||||
nuscaleMode = new NUScaleModBoxCMode(this, ip);
|
||||
squashMode = new SquashModBoxCMode(this, ip);
|
||||
selectMode = new SelectModBoxCMode(this, ip);
|
||||
extrudeMode = new EPM_ExtrudeCMode(this, ip);
|
||||
bevelMode = new EPM_BevelCMode(this, ip);
|
||||
bindMode = new EPM_BindCMode(this, ip);
|
||||
|
||||
|
||||
// Add our sub object type
|
||||
TSTR type1(GetString(IDS_TH_VERTEX));
|
||||
TSTR type2(GetString(IDS_TH_EDGE));
|
||||
TSTR type3(GetString(IDS_TH_PATCH));
|
||||
TSTR type4("Tile");
|
||||
const TCHAR *ptype[] = { type1, type2, type3 , type4 };
|
||||
ip->RegisterSubObjectTypes(ptype, 4);
|
||||
|
||||
// Restore the selection level.
|
||||
ip->SetSubObjectLevel(selLevel);
|
||||
|
||||
// Disable show end result.
|
||||
ip->EnableShowEndResult(FALSE);
|
||||
|
||||
// Setup named selection sets
|
||||
SetupNamedSelDropDown();
|
||||
|
||||
// Update selection UI display
|
||||
SelectionChanged();
|
||||
|
||||
TimeValue t = ip->GetTime();
|
||||
NotifyDependents(Interval(t, t), PART_ALL, REFMSG_BEGIN_EDIT);
|
||||
NotifyDependents(Interval(t, t), PART_ALL, REFMSG_MOD_DISPLAY_ON);
|
||||
SetAFlag(A_MOD_BEING_EDITED);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::EndEditParams(IObjParam *ip, ULONG flags, Animatable *next)
|
||||
{
|
||||
if (hSelectPanel)
|
||||
{
|
||||
rsSel = IsRollupPanelOpen(hSelectPanel);
|
||||
ip->DeleteRollupPage(hSelectPanel);
|
||||
hSelectPanel = NULL;
|
||||
}
|
||||
if (hOpsPanel)
|
||||
{
|
||||
rsOps = IsRollupPanelOpen(hOpsPanel);
|
||||
ip->DeleteRollupPage(hOpsPanel);
|
||||
hOpsPanel = NULL;
|
||||
}
|
||||
if (hSurfPanel)
|
||||
{
|
||||
rsSurf = IsRollupPanelOpen(hSurfPanel);
|
||||
ip->DeleteRollupPage(hSurfPanel);
|
||||
hSurfPanel = NULL;
|
||||
}
|
||||
if (hTilePanel)
|
||||
{
|
||||
rsTile = IsRollupPanelOpen(hTilePanel);
|
||||
ip->DeleteRollupPage(hTilePanel);
|
||||
hTilePanel = NULL;
|
||||
}
|
||||
if (hEdgePanel)
|
||||
{
|
||||
rsEdge = IsRollupPanelOpen(hEdgePanel);
|
||||
ip->DeleteRollupPage(hEdgePanel);
|
||||
hEdgePanel = NULL;
|
||||
}
|
||||
|
||||
// Enable show end result
|
||||
ip->EnableShowEndResult(TRUE);
|
||||
|
||||
CancelEditPatchModes(ip);
|
||||
|
||||
if (ip->GetCommandMode()->ID()==CID_EP_PAINT)
|
||||
ip->SetStdCommandMode(CID_OBJMOVE);
|
||||
|
||||
TimeValue t = ip->GetTime();
|
||||
NotifyDependents(Interval(t, t), PART_ALL, REFMSG_END_EDIT);
|
||||
NotifyDependents(Interval(t, t), PART_ALL, REFMSG_MOD_DISPLAY_OFF);
|
||||
ClearAFlag(A_MOD_BEING_EDITED);
|
||||
|
||||
DeletePatchDataTempData();
|
||||
this->ip = NULL;
|
||||
|
||||
// if ( ip->GetCommandMode()->ID() == CID_EP_EXTRUDE ) ip->SetStdCommandMode( CID_OBJMOVE );
|
||||
// if ( ip->GetCommandMode()->ID() == CID_EP_BEVEL ) ip->SetStdCommandMode( CID_OBJMOVE );
|
||||
|
||||
ip->DeleteMode(moveMode);
|
||||
ip->DeleteMode(rotMode);
|
||||
ip->DeleteMode(uscaleMode);
|
||||
ip->DeleteMode(nuscaleMode);
|
||||
ip->DeleteMode(squashMode);
|
||||
ip->DeleteMode(selectMode);
|
||||
ip->DeleteMode(extrudeMode);
|
||||
ip->DeleteMode(bevelMode);
|
||||
ip->DeleteMode(bindMode);
|
||||
|
||||
if (moveMode)
|
||||
delete moveMode;
|
||||
moveMode = NULL;
|
||||
if (rotMode)
|
||||
delete rotMode;
|
||||
rotMode = NULL;
|
||||
if (uscaleMode)
|
||||
delete uscaleMode;
|
||||
uscaleMode = NULL;
|
||||
if (nuscaleMode)
|
||||
delete nuscaleMode;
|
||||
nuscaleMode = NULL;
|
||||
if (squashMode)
|
||||
delete squashMode;
|
||||
squashMode = NULL;
|
||||
if (selectMode)
|
||||
delete selectMode;
|
||||
selectMode = NULL;
|
||||
|
||||
if (extrudeMode)
|
||||
delete extrudeMode;
|
||||
extrudeMode = NULL;
|
||||
|
||||
if (bevelMode)
|
||||
delete bevelMode;
|
||||
bevelMode = NULL;
|
||||
if (bindMode)
|
||||
delete bindMode;
|
||||
bindMode = NULL;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
EditPatchMod::EditPatchMod()
|
||||
{
|
||||
selLevel = EP_OBJECT;
|
||||
displayLattice = TRUE;
|
||||
displaySurface = TRUE;
|
||||
propagate = TRUE;
|
||||
meshSteps = 5;
|
||||
transitionType = 1;
|
||||
channelModified = EDITPAT_CHANNELS;
|
||||
// 3-18-99 to suport render steps and removal of the mental tesselator
|
||||
meshStepsRender = 5;
|
||||
showInterior = TRUE;
|
||||
|
||||
namedSelNeedsFixup = FALSE;
|
||||
includeMeshes=false;
|
||||
// meshAdaptive = FALSE; // Future use (Not used now)
|
||||
}
|
||||
|
||||
EditPatchMod::~EditPatchMod()
|
||||
{
|
||||
ClearSetNames();
|
||||
}
|
@ -1,197 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
extern Point3 zeroPoint;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
PatchPointTab::PatchPointTab()
|
||||
{
|
||||
}
|
||||
|
||||
PatchPointTab::~PatchPointTab()
|
||||
{
|
||||
}
|
||||
|
||||
void PatchPointTab::Empty()
|
||||
{
|
||||
ptab.Delete(0, ptab.Count());
|
||||
vtab.Delete(0, vtab.Count());
|
||||
pttab.Delete(0, pttab.Count());
|
||||
}
|
||||
|
||||
void PatchPointTab::Zero()
|
||||
{
|
||||
// DebugPrint("Zeroing\n");
|
||||
int points = ptab.Count();
|
||||
int vectors = vtab.Count();
|
||||
Point3 zero(0, 0, 0);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < points; ++i)
|
||||
{
|
||||
ptab[i] = zero;
|
||||
pttab[i] = 0;
|
||||
}
|
||||
for (i = 0; i < vectors; ++i)
|
||||
vtab[i] = zero;
|
||||
}
|
||||
|
||||
void PatchPointTab::MakeCompatible(PatchMesh& patch, int clear)
|
||||
{
|
||||
int izero = 0;
|
||||
if (clear)
|
||||
{
|
||||
ptab.Delete(0, ptab.Count());
|
||||
pttab.Delete(0, pttab.Count());
|
||||
vtab.Delete(0, vtab.Count());
|
||||
}
|
||||
// First, the verts
|
||||
int size = patch.numVerts;
|
||||
if (ptab.Count() > size)
|
||||
{
|
||||
int diff = ptab.Count() - size;
|
||||
ptab.Delete(ptab.Count() - diff, diff);
|
||||
pttab.Delete(pttab.Count() - diff, diff);
|
||||
}
|
||||
if (ptab.Count() < size)
|
||||
{
|
||||
int diff = size - ptab.Count();
|
||||
ptab.Resize(size);
|
||||
pttab.Resize(size);
|
||||
for (int j = 0; j < diff; j++)
|
||||
{
|
||||
ptab.Append(1, &zeroPoint);
|
||||
pttab.Append(1, &izero);
|
||||
}
|
||||
}
|
||||
// Now, the vectors
|
||||
size = patch.numVecs;
|
||||
if (vtab.Count() > size)
|
||||
{
|
||||
int diff = vtab.Count() - size;
|
||||
vtab.Delete(vtab.Count() - diff, diff);
|
||||
}
|
||||
if (vtab.Count() < size)
|
||||
{
|
||||
int diff = size - vtab.Count();
|
||||
vtab.Resize(size);
|
||||
for (int j = 0; j < diff; j++)
|
||||
vtab.Append(1, &zeroPoint);
|
||||
}
|
||||
}
|
||||
|
||||
PatchPointTab& PatchPointTab::operator=(PatchPointTab& from)
|
||||
{
|
||||
ptab = from.ptab;
|
||||
vtab = from.vtab;
|
||||
pttab = from.pttab;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BOOL PatchPointTab::IsCompatible(PatchMesh &patch)
|
||||
{
|
||||
if (ptab.Count() != patch.numVerts)
|
||||
return FALSE;
|
||||
if (pttab.Count() != patch.numVerts)
|
||||
return FALSE;
|
||||
if (vtab.Count() != patch.numVecs)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void PatchPointTab::RescaleWorldUnits(float f)
|
||||
{
|
||||
Matrix3 stm = ScaleMatrix(Point3(f, f, f));
|
||||
int points = ptab.Count();
|
||||
int vectors = vtab.Count();
|
||||
|
||||
int i;
|
||||
for (i = 0; i < points; ++i)
|
||||
ptab[i] = ptab[i] * stm;
|
||||
for (i = 0; i < vectors; ++i)
|
||||
vtab[i] = vtab[i] * stm;
|
||||
}
|
||||
|
||||
#define PPT_VERT_CHUNK 0x1000
|
||||
#define PPT_VEC_CHUNK 0x1010
|
||||
#define PPT_VERTTYPE_CHUNK 0x1020
|
||||
|
||||
IOResult PatchPointTab::Save(ISave *isave)
|
||||
{
|
||||
int i;
|
||||
ULONG nb;
|
||||
isave->BeginChunk(PPT_VERT_CHUNK);
|
||||
int count = ptab.Count();
|
||||
isave->Write(&count, sizeof(int), &nb);
|
||||
for (i = 0; i < count; ++i)
|
||||
isave->Write(&ptab[i], sizeof(Point3), &nb);
|
||||
isave->EndChunk();
|
||||
isave->BeginChunk(PPT_VERTTYPE_CHUNK);
|
||||
count = pttab.Count();
|
||||
isave->Write(&count, sizeof(int), &nb);
|
||||
for (i = 0; i < count; ++i)
|
||||
isave->Write(&pttab[i], sizeof(int), &nb);
|
||||
isave->EndChunk();
|
||||
isave->BeginChunk(PPT_VEC_CHUNK);
|
||||
count = vtab.Count();
|
||||
isave->Write(&count, sizeof(int), &nb);
|
||||
for (i = 0; i < count; ++i)
|
||||
isave->Write(&vtab[i], sizeof(Point3), &nb);
|
||||
isave->EndChunk();
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
IOResult PatchPointTab::Load(ILoad *iload)
|
||||
{
|
||||
int i, count;
|
||||
Point3 workpt;
|
||||
int workint;
|
||||
IOResult res;
|
||||
ULONG nb;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case PPT_VERT_CHUNK:
|
||||
ptab.Delete(0, ptab.Count());
|
||||
iload->Read(&count, sizeof(int), &nb);
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
iload->Read(&workpt, sizeof(Point3), &nb);
|
||||
ptab.Append(1, &workpt);
|
||||
}
|
||||
break;
|
||||
case PPT_VERTTYPE_CHUNK:
|
||||
pttab.Delete(0, pttab.Count());
|
||||
iload->Read(&count, sizeof(int), &nb);
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
iload->Read(&workint, sizeof(int), &nb);
|
||||
pttab.Append(1, &workint);
|
||||
}
|
||||
break;
|
||||
case PPT_VEC_CHUNK:
|
||||
vtab.Delete(0, vtab.Count());
|
||||
iload->Read(&count, sizeof(int), &nb);
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
iload->Read(&workpt, sizeof(Point3), &nb);
|
||||
vtab.Append(1, &workpt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
@ -1,123 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
extern void Cancel2StepPatchModes(IObjParam *ip);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
PatchRestore::PatchRestore(EditPatchData* pd, EditPatchMod* mod, PatchMesh *patch, RPatchMesh *rpatch, TCHAR *id)
|
||||
{
|
||||
gotRedo = FALSE;
|
||||
epd = pd;
|
||||
this->mod = mod;
|
||||
oldPatch = *patch;
|
||||
|
||||
roldPatch=NULL;
|
||||
rnewPatch=NULL;
|
||||
|
||||
// rpatch
|
||||
if (rpatch)
|
||||
{
|
||||
roldPatch=new RPatchMesh();
|
||||
*roldPatch = *rpatch;
|
||||
}
|
||||
|
||||
t = mod->ip->GetTime();
|
||||
where = TSTR(id);
|
||||
}
|
||||
|
||||
PatchRestore::~PatchRestore()
|
||||
{
|
||||
if (roldPatch)
|
||||
delete roldPatch;
|
||||
if (rnewPatch)
|
||||
delete rnewPatch;
|
||||
}
|
||||
|
||||
void PatchRestore::Restore(int isUndo)
|
||||
{
|
||||
if (epd->tempData && epd->TempData(mod)->PatchCached(t))
|
||||
{
|
||||
RPatchMesh *rpatch;
|
||||
PatchMesh *patch = epd->TempData(mod)->GetPatch(t,rpatch);
|
||||
if (patch)
|
||||
{
|
||||
if (isUndo && !gotRedo)
|
||||
{
|
||||
newPatch = *patch;
|
||||
|
||||
// rpatch
|
||||
if (!rnewPatch)
|
||||
rnewPatch = new RPatchMesh();
|
||||
|
||||
*rnewPatch = *rpatch;
|
||||
|
||||
gotRedo = TRUE;
|
||||
}
|
||||
}
|
||||
DWORD selLevel = patch->selLevel; // Grab this...
|
||||
DWORD dispFlags = patch->dispFlags; // Grab this...
|
||||
*patch = oldPatch;
|
||||
|
||||
if (roldPatch)
|
||||
*rpatch = *roldPatch;
|
||||
|
||||
patch->selLevel = selLevel; // ...and put it back in
|
||||
patch->dispFlags = dispFlags; // ...and put it back in
|
||||
patch->InvalidateGeomCache();
|
||||
epd->TempData(mod)->Invalidate(PART_GEOM | PART_TOPO | PART_SELECT);
|
||||
}
|
||||
else
|
||||
if (epd->tempData)
|
||||
{
|
||||
epd->TempData(mod)->Invalidate(PART_GEOM | PART_TOPO | PART_SELECT, FALSE);
|
||||
}
|
||||
if (mod->ip)
|
||||
Cancel2StepPatchModes(mod->ip);
|
||||
mod->InvalidateSurfaceUI();
|
||||
mod->SelectionChanged();
|
||||
mod->NotifyDependents(FOREVER, PART_GEOM | PART_TOPO | PART_SELECT, REFMSG_CHANGE);
|
||||
}
|
||||
|
||||
void PatchRestore::Redo()
|
||||
{
|
||||
if (epd->tempData && epd->TempData(mod)->PatchCached(t))
|
||||
{
|
||||
RPatchMesh *rpatch;
|
||||
PatchMesh *patch = epd->TempData(mod)->GetPatch(t,rpatch);
|
||||
if (patch)
|
||||
{
|
||||
DWORD selLevel = patch->selLevel; // Grab this...
|
||||
DWORD dispFlags = patch->dispFlags; // Grab this...
|
||||
*patch = newPatch;
|
||||
|
||||
nlassert (rnewPatch); // should not be NULL
|
||||
*rpatch = *rnewPatch;
|
||||
|
||||
patch->selLevel = selLevel; // ...and put it back in
|
||||
patch->dispFlags = dispFlags; // ...and put it back in
|
||||
patch->InvalidateGeomCache();
|
||||
}
|
||||
epd->TempData(mod)->Invalidate(PART_GEOM | PART_TOPO | PART_SELECT);
|
||||
}
|
||||
else
|
||||
if (epd->tempData)
|
||||
{
|
||||
epd->TempData(mod)->Invalidate(PART_GEOM | PART_TOPO | PART_SELECT, FALSE);
|
||||
}
|
||||
if (mod->ip)
|
||||
Cancel2StepPatchModes(mod->ip);
|
||||
mod->InvalidateSurfaceUI();
|
||||
mod->SelectionChanged();
|
||||
mod->NotifyDependents(FOREVER, PART_GEOM | PART_TOPO | PART_SELECT, REFMSG_CHANGE);
|
||||
}
|
||||
|
||||
|
@ -1,87 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
extern void Cancel2StepPatchModes(IObjParam *ip);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
PatchSelRestore::PatchSelRestore(EditPatchData* pd, EditPatchMod* mod, PatchMesh *patch)
|
||||
{
|
||||
gotRedo = FALSE;
|
||||
epd = pd;
|
||||
this->mod = mod;
|
||||
oldVSel = patch->vertSel;
|
||||
oldESel = patch->edgeSel;
|
||||
oldPSel = patch->patchSel;
|
||||
t = mod->ip->GetTime();
|
||||
}
|
||||
|
||||
void PatchSelRestore::Restore(int isUndo)
|
||||
{
|
||||
if (epd->tempData && epd->TempData(mod)->PatchCached(t))
|
||||
{
|
||||
RPatchMesh *rpatch;
|
||||
PatchMesh *patch = epd->TempData(mod)->GetPatch(t, rpatch);
|
||||
if (patch)
|
||||
{
|
||||
if (isUndo && !gotRedo)
|
||||
{
|
||||
newVSel = patch->vertSel;
|
||||
newESel = patch->edgeSel;
|
||||
newPSel = patch->patchSel;
|
||||
gotRedo = TRUE;
|
||||
}
|
||||
}
|
||||
patch->vertSel = oldVSel;
|
||||
patch->edgeSel = oldESel;
|
||||
patch->patchSel = oldPSel;
|
||||
epd->TempData(mod)->Invalidate(PART_GEOM | PART_TOPO | PART_SELECT);
|
||||
}
|
||||
else
|
||||
if (epd->tempData)
|
||||
{
|
||||
epd->TempData(mod)->Invalidate(PART_GEOM | PART_TOPO | PART_SELECT, FALSE);
|
||||
}
|
||||
if (mod->ip)
|
||||
Cancel2StepPatchModes(mod->ip);
|
||||
mod->InvalidateSurfaceUI();
|
||||
// mod->PatchSelChanged();
|
||||
// mod->UpdateSelectDisplay();
|
||||
mod->NotifyDependents(FOREVER, PART_GEOM | PART_TOPO | PART_SELECT, REFMSG_CHANGE);
|
||||
}
|
||||
|
||||
void PatchSelRestore::Redo()
|
||||
{
|
||||
if (epd->tempData && epd->TempData(mod)->PatchCached(t))
|
||||
{
|
||||
RPatchMesh *rpatch;
|
||||
PatchMesh *patch = epd->TempData(mod)->GetPatch(t,rpatch);
|
||||
if (patch)
|
||||
{
|
||||
patch->vertSel = newVSel;
|
||||
patch->edgeSel = newESel;
|
||||
patch->patchSel = newPSel;
|
||||
}
|
||||
epd->TempData(mod)->Invalidate(PART_GEOM | PART_TOPO | PART_SELECT);
|
||||
}
|
||||
else
|
||||
if (epd->tempData)
|
||||
{
|
||||
epd->TempData(mod)->Invalidate(PART_GEOM | PART_TOPO | PART_SELECT, FALSE);
|
||||
}
|
||||
if (mod->ip)
|
||||
Cancel2StepPatchModes(mod->ip);
|
||||
mod->InvalidateSurfaceUI();
|
||||
// mod->PatchSelChanged();
|
||||
// mod->UpdateSelectDisplay();
|
||||
mod->NotifyDependents(FOREVER, PART_GEOM | PART_TOPO | PART_SELECT, REFMSG_CHANGE);
|
||||
}
|
||||
|
@ -1,138 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
void PatchVertexDelta::SetSize(PatchMesh& patch, BOOL load)
|
||||
{
|
||||
dtab.MakeCompatible(patch, FALSE);
|
||||
|
||||
// Load it if necessary
|
||||
if (load)
|
||||
{
|
||||
int verts = patch.numVerts;
|
||||
int vecs = patch.numVecs;
|
||||
int i;
|
||||
for (i = 0; i < verts; ++i)
|
||||
{
|
||||
dtab.ptab[i] = patch.verts[i].p;
|
||||
dtab.pttab[i] = patch.verts[i].flags & PVERT_COPLANAR;
|
||||
}
|
||||
for (i = 0; i < vecs; ++i)
|
||||
dtab.vtab[i] = patch.vecs[i].p;
|
||||
}
|
||||
}
|
||||
|
||||
void PatchVertexDelta::Apply(PatchMesh &patch)
|
||||
{
|
||||
// DebugPrint(_T("PVD:Applying\n"));
|
||||
// This does nothing if the number of verts hasn't changed in the mesh.
|
||||
SetSize(patch, FALSE);
|
||||
|
||||
// Apply the deltas
|
||||
int verts = patch.numVerts;
|
||||
int vecs = patch.numVecs;
|
||||
int i;
|
||||
for (i = 0; i < verts; ++i)
|
||||
{
|
||||
patch.verts[i].p += dtab.ptab[i];
|
||||
patch.verts[i].flags ^= dtab.pttab[i];
|
||||
}
|
||||
for (i = 0; i < vecs; ++i)
|
||||
{
|
||||
patch.vecs[i].p += dtab.vtab[i];
|
||||
}
|
||||
patch.computeInteriors();
|
||||
}
|
||||
|
||||
void PatchVertexDelta::UnApply(PatchMesh &patch)
|
||||
{
|
||||
// DebugPrint(_T("PVD:UnApplying\n"));
|
||||
// This does nothing if the number of verts hasn't changed in the mesh.
|
||||
SetSize(patch, FALSE);
|
||||
|
||||
// Apply the deltas
|
||||
int verts = patch.numVerts;
|
||||
int vecs = patch.numVecs;
|
||||
int i;
|
||||
for (i = 0; i < verts; ++i)
|
||||
{
|
||||
patch.verts[i].p -= dtab.ptab[i];
|
||||
patch.verts[i].flags ^= dtab.pttab[i];
|
||||
}
|
||||
for (i = 0; i < vecs; ++i)
|
||||
{
|
||||
patch.vecs[i].p -= dtab.vtab[i];
|
||||
}
|
||||
patch.computeInteriors();
|
||||
}
|
||||
|
||||
// This function applies the current changes to slave handles and their knots, and zeroes everything else
|
||||
void PatchVertexDelta::ApplyHandlesAndZero(PatchMesh &patch, int handleVert)
|
||||
{
|
||||
// DebugPrint(_T("PVD:ApplyAndZero\n"));
|
||||
// This does nothing if the number of verts hasn't changed in the mesh.
|
||||
SetSize(patch, FALSE);
|
||||
|
||||
Point3 zeroPt(0.0f, 0.0f, 0.0f);
|
||||
|
||||
// Apply the deltas to just the slave handles
|
||||
int verts = patch.numVerts;
|
||||
int vecs = patch.numVecs;
|
||||
Point3Tab& delta = dtab.vtab;
|
||||
IntTab& kdelta = dtab.pttab;
|
||||
int i;
|
||||
for (i = 0; i < vecs; ++i)
|
||||
{
|
||||
if (!(delta[i] == zeroPt))
|
||||
{
|
||||
if (i != handleVert)
|
||||
patch.vecs[i].p += delta[i];
|
||||
else
|
||||
delta[i] = zeroPt;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < verts; ++i)
|
||||
{
|
||||
if (kdelta[i])
|
||||
patch.verts[i].flags ^= kdelta[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define PVD_POINTTAB_CHUNK 0x1000
|
||||
|
||||
IOResult PatchVertexDelta::Save(ISave *isave)
|
||||
{
|
||||
isave->BeginChunk(PVD_POINTTAB_CHUNK);
|
||||
dtab.Save(isave);
|
||||
isave-> EndChunk();
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
IOResult PatchVertexDelta::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case PVD_POINTTAB_CHUNK:
|
||||
res = dtab.Load(iload);
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
@ -1,138 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL PickPatchAttach::Filter(INode *node)
|
||||
{
|
||||
ModContextList mcList;
|
||||
INodeTab nodes;
|
||||
if (node)
|
||||
{
|
||||
// Make sure the node does not depend on us
|
||||
node->BeginDependencyTest();
|
||||
ep->NotifyDependents(FOREVER, 0, REFMSG_TEST_DEPENDENCY);
|
||||
if (node->EndDependencyTest())
|
||||
return FALSE;
|
||||
|
||||
ObjectState os = node->GetObjectRef()->Eval(ep->ip->GetTime());
|
||||
GeomObject *object =(GeomObject *)os.obj;
|
||||
// Make sure it isn't one of the nodes we're editing, for heaven's sake!
|
||||
ep->ip->GetModContexts(mcList, nodes);
|
||||
int numNodes = nodes.Count();
|
||||
for (int i = 0; i < numNodes; ++i)
|
||||
{
|
||||
if (nodes[i] == node)
|
||||
{
|
||||
nodes.DisposeTemporary();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (object->CanConvertToType(RYKOLPATCHOBJ_CLASS_ID))
|
||||
{
|
||||
nodes.DisposeTemporary();
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
nodes.DisposeTemporary();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL PickPatchAttach::HitTest(
|
||||
IObjParam *ip, HWND hWnd, ViewExp *vpt, IPoint2 m, int flags)
|
||||
{
|
||||
INode *node = ip->PickNode(hWnd, m, this);
|
||||
ModContextList mcList;
|
||||
INodeTab nodes;
|
||||
|
||||
if (node)
|
||||
{
|
||||
ObjectState os = node->GetObjectRef()->Eval(ip->GetTime());
|
||||
GeomObject *object =(GeomObject *)os.obj;
|
||||
// Make sure it isn't one of the nodes we're editing, for heaven's sake!
|
||||
ep->ip->GetModContexts(mcList, nodes);
|
||||
int numNodes = nodes.Count();
|
||||
for (int i = 0; i < numNodes; ++i)
|
||||
{
|
||||
if (nodes[i] == node)
|
||||
{
|
||||
nodes.DisposeTemporary();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (object->CanConvertToType(RYKOLPATCHOBJ_CLASS_ID))
|
||||
{
|
||||
nodes.DisposeTemporary();
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
nodes.DisposeTemporary();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL PickPatchAttach::Pick(IObjParam *ip, ViewExp *vpt)
|
||||
{
|
||||
INode *node = vpt->GetClosestHit();
|
||||
nlassert(node);
|
||||
GeomObject *object =(GeomObject *)node->GetObjectRef()->Eval(ip->GetTime()).obj;
|
||||
if (object->CanConvertToType(RYKOLPATCHOBJ_CLASS_ID))
|
||||
{
|
||||
RPO *attPatch =(RPO *)object->ConvertToType(ip->GetTime(), RYKOLPATCHOBJ_CLASS_ID);
|
||||
if (attPatch)
|
||||
{
|
||||
PatchMesh patch = attPatch->patch;
|
||||
RPatchMesh rpatch = *attPatch->rpatch;
|
||||
ModContextList mcList;
|
||||
INodeTab nodes;
|
||||
ip->GetModContexts(mcList, nodes);
|
||||
BOOL res = TRUE;
|
||||
if (nodes[0]->GetMtl() && node->GetMtl() &&(nodes[0]->GetMtl() != node->GetMtl()))
|
||||
res = DoAttachMatOptionDialog(ep->ip, ep);
|
||||
if (res)
|
||||
{
|
||||
bool canUndo = TRUE;
|
||||
ep->DoAttach(node, &patch, &rpatch, canUndo);
|
||||
if (!canUndo)
|
||||
GetSystemSetting(SYSSET_CLEAR_UNDO);
|
||||
}
|
||||
nodes.DisposeTemporary();
|
||||
// Discard the copy it made, if it isn't the same as the object itself
|
||||
if (attPatch !=(PatchObject *)object)
|
||||
delete attPatch;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void PickPatchAttach::EnterMode(IObjParam *ip)
|
||||
{
|
||||
if (ep->hOpsPanel)
|
||||
{
|
||||
ICustButton *but = GetICustButton(GetDlgItem(ep->hOpsPanel, IDC_ATTACH));
|
||||
but->SetCheck(TRUE);
|
||||
ReleaseICustButton(but);
|
||||
}
|
||||
}
|
||||
|
||||
void PickPatchAttach::ExitMode(IObjParam *ip)
|
||||
{
|
||||
if (ep->hOpsPanel)
|
||||
{
|
||||
ICustButton *but = GetICustButton(GetDlgItem(ep->hOpsPanel, IDC_ATTACH));
|
||||
but->SetCheck(FALSE);
|
||||
ReleaseICustButton(but);
|
||||
}
|
||||
}
|
||||
|
||||
HCURSOR PickPatchAttach::GetHitCursor(IObjParam *ip)
|
||||
{
|
||||
return LoadCursor(hInstance, MAKEINTRESOURCE(IDC_ATTACHCUR));
|
||||
}
|
@ -1,895 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
#define PROMPT_TIME 2000
|
||||
|
||||
extern void DeletePatchParts(PatchMesh *patch, RPatchMesh *rpatch, BitArray &delVerts, BitArray &delPatches);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
static BOOL IsCompatible(BitArray &a, BitArray &b)
|
||||
{
|
||||
return (a.GetSize() == b.GetSize()) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOL ClearPVertSelRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (reRecord)
|
||||
sel = patch->vertSel;
|
||||
patch->vertSel.ClearAll();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define CVSR_SEL_CHUNK 0x1000
|
||||
|
||||
IOResult ClearPVertSelRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case CVSR_SEL_CHUNK:
|
||||
res = sel.Load(iload);
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
BOOL SetPVertSelRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (reRecord)
|
||||
sel = patch->vertSel;
|
||||
patch->vertSel.SetAll();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define SVSR_SEL_CHUNK 0x1000
|
||||
|
||||
IOResult SetPVertSelRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case SVSR_SEL_CHUNK:
|
||||
res = sel.Load(iload);
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL InvertPVertSelRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
patch->vertSel = ~patch->vertSel;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
IOResult InvertPVertSelRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
// switch(iload->CurChunkID()) {
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL ClearPEdgeSelRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (reRecord)
|
||||
sel = patch->edgeSel;
|
||||
patch->edgeSel.ClearAll();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define CESR_SEL_CHUNK 0x1000
|
||||
|
||||
IOResult ClearPEdgeSelRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case CESR_SEL_CHUNK:
|
||||
res = sel.Load(iload);
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL SetPEdgeSelRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (reRecord)
|
||||
sel = patch->edgeSel;
|
||||
patch->edgeSel.SetAll();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define SESR_SEL_CHUNK 0x1000
|
||||
|
||||
IOResult SetPEdgeSelRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case SESR_SEL_CHUNK:
|
||||
res = sel.Load(iload);
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL InvertPEdgeSelRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
patch->edgeSel = ~patch->edgeSel;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
IOResult InvertPEdgeSelRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
// switch(iload->CurChunkID()) {
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL ClearPatchSelRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (reRecord)
|
||||
sel = patch->patchSel;
|
||||
patch->patchSel.ClearAll();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define CPSR_SEL_CHUNK 0x1000
|
||||
|
||||
IOResult ClearPatchSelRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case CPSR_SEL_CHUNK:
|
||||
res = sel.Load(iload);
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL SetPatchSelRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (reRecord)
|
||||
sel = patch->patchSel;
|
||||
patch->patchSel.SetAll();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define SPSR_SEL_CHUNK 0x1000
|
||||
|
||||
IOResult SetPatchSelRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case SPSR_SEL_CHUNK:
|
||||
res = sel.Load(iload);
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL InvertPatchSelRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
patch->patchSel = ~patch->patchSel;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
IOResult InvertPatchSelRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
// switch(iload->CurChunkID()) {
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL PVertSelRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (!IsCompatible(patch->vertSel, newSel))
|
||||
return FALSE;
|
||||
patch->vertSel = newSel;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define VSR_OLDSEL_CHUNK 0x1000
|
||||
#define VSR_NEWSEL_CHUNK 0x1010
|
||||
|
||||
IOResult PVertSelRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case VSR_OLDSEL_CHUNK:
|
||||
res = oldSel.Load(iload);
|
||||
break;
|
||||
case VSR_NEWSEL_CHUNK:
|
||||
res = newSel.Load(iload);
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL PEdgeSelRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (!IsCompatible(patch->edgeSel, newSel))
|
||||
return FALSE;
|
||||
patch->edgeSel = newSel;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define ESR_OLDSEL_CHUNK 0x1000
|
||||
#define ESR_NEWSEL_CHUNK 0x1010
|
||||
|
||||
IOResult PEdgeSelRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case ESR_OLDSEL_CHUNK:
|
||||
res = oldSel.Load(iload);
|
||||
break;
|
||||
case ESR_NEWSEL_CHUNK:
|
||||
res = newSel.Load(iload);
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL PatchSelRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (!IsCompatible(patch->patchSel, newSel))
|
||||
return FALSE;
|
||||
patch->patchSel = newSel;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define PSR_OLDSEL_CHUNK 0x1000
|
||||
#define PSR_NEWSEL_CHUNK 0x1010
|
||||
|
||||
IOResult PatchSelRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case PSR_OLDSEL_CHUNK:
|
||||
res = oldSel.Load(iload);
|
||||
break;
|
||||
case PSR_NEWSEL_CHUNK:
|
||||
res = newSel.Load(iload);
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define PDELR_PATCH_CHUNK 0x1060
|
||||
|
||||
IOResult PatchDeleteRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
// switch(iload->CurChunkID()) {
|
||||
// case PDELR_PATCH_CHUNK:
|
||||
// res = oldPatch.Load(iload);
|
||||
// break;
|
||||
// }
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL PVertMoveRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (!delta.IsCompatible(*patch))
|
||||
return FALSE;
|
||||
delta.Apply(*patch);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define VMR_DELTA_CHUNK 0x1000
|
||||
|
||||
IOResult PVertMoveRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case VMR_DELTA_CHUNK:
|
||||
res = delta.Load(iload);
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
extern void DeleteSelVerts(PatchMesh *patch, RPatchMesh *rpatch);
|
||||
|
||||
BOOL PVertDeleteRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (reRecord)
|
||||
{
|
||||
oldPatch = *patch;
|
||||
roldPatch = *rpatch;
|
||||
}
|
||||
DeleteSelVerts(patch, rpatch);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define VDELR_PATCH_CHUNK 0x1060
|
||||
|
||||
IOResult PVertDeleteRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
// switch(iload->CurChunkID()) {
|
||||
// case VDELR_PATCH_CHUNK:
|
||||
// res = oldPatch.Load(iload);
|
||||
// break;
|
||||
// }
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL PVertChangeRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (reRecord)
|
||||
{
|
||||
oldPatch = *patch;
|
||||
roldPatch = *rpatch;
|
||||
}
|
||||
patch->ChangeVertType(index, type);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define VCHG_GENERAL_CHUNK 0x1001
|
||||
#define VCHG_PATCH_CHUNK 0x1010
|
||||
|
||||
IOResult PVertChangeRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
ULONG nb;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case VCHG_GENERAL_CHUNK:
|
||||
res = iload->Read(&index, sizeof(int), &nb);
|
||||
res = iload->Read(&type, sizeof(int), &nb);
|
||||
break;
|
||||
// case VCHG_PATCH_CHUNK:
|
||||
// res = oldPatch.Load(iload);
|
||||
// break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL PAttachRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (reRecord)
|
||||
oldPatchCount = patch->numPatches;
|
||||
patch->Attach(&attPatch, mtlOffset);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define ATTR_GENERAL_CHUNK 0x1001
|
||||
#define ATTR_ATTPATCH_CHUNK 0x1010
|
||||
#define ATTR_MTLOFFSET_CHUNK 0x1020
|
||||
|
||||
IOResult PAttachRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
ULONG nb;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case ATTR_GENERAL_CHUNK:
|
||||
res = iload->Read(&oldPatchCount, sizeof(int), &nb);
|
||||
break;
|
||||
case ATTR_ATTPATCH_CHUNK:
|
||||
res = attPatch.Load(iload);
|
||||
break;
|
||||
case ATTR_MTLOFFSET_CHUNK:
|
||||
res = iload->Read(&mtlOffset, sizeof(int), &nb);
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL PatchDetachRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (reRecord && !copy)
|
||||
{
|
||||
oldPatch = *patch;
|
||||
roldPatch = *rpatch;
|
||||
}
|
||||
if (!copy)
|
||||
{
|
||||
BitArray vdel(patch->numVerts);
|
||||
vdel.ClearAll();
|
||||
BitArray pdel = patch->patchSel;
|
||||
DeletePatchParts(patch, rpatch, vdel, pdel);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define PDETR_GENERAL_CHUNK 0x1000
|
||||
#define PDETR_PATCH_CHUNK 0x1030
|
||||
|
||||
IOResult PatchDetachRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
ULONG nb;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case PDETR_GENERAL_CHUNK:
|
||||
res = iload->Read(©, sizeof(int), &nb);
|
||||
break;
|
||||
// case PDETR_PATCH_CHUNK:
|
||||
// res = oldPatch.Load(iload);
|
||||
// break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL PatchMtlRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
for (int i = 0; i < patch->numPatches; ++i)
|
||||
{
|
||||
if (patch->patchSel[i])
|
||||
patch->patches[i].setMatID(index);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define PMTLR_GENERAL_CHUNK 0x1000
|
||||
#define PMTLR_INDEX_CHUNK 0x1020
|
||||
|
||||
IOResult PatchMtlRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
ULONG nb;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case PMTLR_INDEX_CHUNK:
|
||||
res = iload->Read(&index, sizeof(MtlID), &nb);
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void ChangePatchType(PatchMesh *patch, int index, int type)
|
||||
{
|
||||
// If positive vertex number, do it to just one vertex
|
||||
if (index >= 0)
|
||||
{
|
||||
patch->patches[index].flags = type;
|
||||
patch->computeInteriors();
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, do it to all selected vertices!
|
||||
int patches = patch->numPatches;
|
||||
BitArray &psel = patch->patchSel;
|
||||
for (int i = 0; i < patches; ++i)
|
||||
{
|
||||
if (psel[i])
|
||||
patch->patches[i].flags = type;
|
||||
}
|
||||
patch->computeInteriors();
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOL PatchChangeRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (index >= 0 && index >= patch->numPatches)
|
||||
return FALSE;
|
||||
if (reRecord)
|
||||
{
|
||||
oldPatch = *patch;
|
||||
roldPatch = *rpatch;
|
||||
}
|
||||
ChangePatchType(patch, index, type);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define PCHG_GENERAL_CHUNK 0x1001
|
||||
#define PCHG_PATCH_CHUNK 0x1010
|
||||
|
||||
IOResult PatchChangeRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
ULONG nb;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case PCHG_GENERAL_CHUNK:
|
||||
res = iload->Read(&index, sizeof(int), &nb);
|
||||
res = iload->Read(&type, sizeof(int), &nb);
|
||||
break;
|
||||
// case PCHG_PATCH_CHUNK:
|
||||
// res = oldPatch.Load(iload);
|
||||
// break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define PADDR_TYPE_CHUNK 0x1000
|
||||
#define PADDR_PATCH_CHUNK 0x1010
|
||||
#define PADDR_POSTWELD_CHUNK 0x1020
|
||||
|
||||
IOResult PatchAddRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
ULONG nb;
|
||||
postWeld = FALSE;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case PADDR_TYPE_CHUNK:
|
||||
res = iload->Read(&type, sizeof(int), &nb);
|
||||
break;
|
||||
// case PADDR_PATCH_CHUNK:
|
||||
// res = oldPatch.Load(iload);
|
||||
// break;
|
||||
// If the following chunk is present, it's a MAX 2.0 file and a post-addition
|
||||
// weld is to be performed
|
||||
case PADDR_POSTWELD_CHUNK:
|
||||
postWeld = TRUE;
|
||||
break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Compute midpoint division for patch vectors -- Provide patchmesh, patch number, 4 bez points
|
||||
// returns 2 new vectors
|
||||
/*
|
||||
static Point3 InterpPoint(PatchMesh *patch, int index, float pct, int e1, int i1, int i2, int e2, Point3 *v1 = NULL, Point3 *v2 = NULL, Point3 *v3 = NULL, Point3 *v4 = NULL)
|
||||
{
|
||||
PatchVec *v = patch->vecs;
|
||||
Patch &p = patch->patches[index];
|
||||
Point3 pe1 = v[p.vec[e1]].p;
|
||||
Point3 pe2 = v[p.vec[e2]].p;
|
||||
Point3 pi1 = v[p.interior[i1]].p;
|
||||
Point3 pi2 = v[p.interior[i2]].p;
|
||||
Point3 e1i1 = pe1 +(pi1 - pe1) * pct;
|
||||
Point3 i1i2 = pi1 +(pi2 - pi1) * pct;
|
||||
Point3 i2e2 = pi2 +(pe2 - pi2) * pct;
|
||||
Point3 a = e1i1 +(i1i2 - e1i1) * pct;
|
||||
Point3 b = i1i2 +(i2e2 - i1i2) * pct;
|
||||
if (v1)
|
||||
*v1 = e1i1;
|
||||
if (v2)
|
||||
*v2 = a;
|
||||
if (v3)
|
||||
*v3 = b;
|
||||
if (v4)
|
||||
*v4 = i2e2;
|
||||
return a +(b - a) * pct;
|
||||
}
|
||||
|
||||
static Point3 InterpPoint(float pct, Point3 e1, Point3 i1, Point3 i2, Point3 e2, Point3 *v1 = NULL, Point3 *v2 = NULL, Point3 *v3 = NULL, Point3 *v4 = NULL)
|
||||
{
|
||||
Point3 e1i1 = e1 +(i1 - e1) * pct;
|
||||
Point3 i1i2 = i1 +(i2 - i1) * pct;
|
||||
Point3 i2e2 = i2 +(e2 - i2) * pct;
|
||||
Point3 a = e1i1 +(i1i2 - e1i1) * pct;
|
||||
Point3 b = i1i2 +(i2e2 - i1i2) * pct;
|
||||
if (v1)
|
||||
*v1 = e1i1;
|
||||
if (v2)
|
||||
*v2 = a;
|
||||
if (v3)
|
||||
*v3 = b;
|
||||
if (v4)
|
||||
*v4 = i2e2;
|
||||
return a +(b - a) * pct;
|
||||
}
|
||||
|
||||
static Point3 InterpLinear(Point3 a, Point3 b, float interp)
|
||||
{
|
||||
return a +(a - b) * interp;
|
||||
}
|
||||
|
||||
static Point3 InterpDegree2(Point3 a, Point3 b, Point3 c, float interp)
|
||||
{
|
||||
Point3 ab = a +(b - a) * interp;
|
||||
Point3 bc = b +(c - b) * interp;
|
||||
return ab +(bc - ab) * interp;
|
||||
}
|
||||
|
||||
static Point3 InterpDegree3(Point3 a, Point3 b, Point3 c, Point3 d, float interp)
|
||||
{
|
||||
Point3 ab = a +(b - a) * interp;
|
||||
Point3 bc = b +(c - b) * interp;
|
||||
Point3 cd = c +(d - c) * interp;
|
||||
Point3 abbc = ab +(bc - ab) * interp;
|
||||
Point3 bccd = bc +(cd - bc) * interp;
|
||||
return abbc +(bccd - abbc) * interp;
|
||||
}
|
||||
*/
|
||||
extern void SubdividePatch(int type, BOOL propagate, PatchMesh *patch, RPatchMesh *rpatch);
|
||||
|
||||
BOOL EdgeSubdivideRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (reRecord)
|
||||
{
|
||||
oldPatch = *patch;
|
||||
roldPatch = *rpatch;
|
||||
}
|
||||
SubdividePatch(SUBDIV_EDGES, propagate, patch, rpatch);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define ESUBR_PROPAGATE_CHUNK 0x1000
|
||||
#define ESUBR_PATCH_CHUNK 0x1010
|
||||
|
||||
IOResult EdgeSubdivideRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
propagate = FALSE;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case ESUBR_PROPAGATE_CHUNK:
|
||||
propagate = TRUE;
|
||||
break;
|
||||
// case ESUBR_PATCH_CHUNK:
|
||||
// res = oldPatch.Load(iload);
|
||||
// break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL PatchSubdivideRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (reRecord)
|
||||
{
|
||||
oldPatch = *patch;
|
||||
roldPatch = *rpatch;
|
||||
}
|
||||
SubdividePatch(SUBDIV_PATCHES, propagate, patch, rpatch);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define PSUBR_PROPAGATE_CHUNK 0x1000
|
||||
#define PSUBR_PATCH_CHUNK 0x1010
|
||||
|
||||
IOResult PatchSubdivideRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
propagate = FALSE;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case PSUBR_PROPAGATE_CHUNK:
|
||||
propagate = TRUE;
|
||||
break;
|
||||
// case PSUBR_PATCH_CHUNK:
|
||||
// res = oldPatch.Load(iload);
|
||||
// break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
||||
|
||||
BOOL PVertWeldRecord::Redo(PatchMesh *patch, RPatchMesh *rpatch, int reRecord)
|
||||
{
|
||||
if (reRecord)
|
||||
{
|
||||
oldPatch = *patch;
|
||||
roldPatch = *rpatch;
|
||||
}
|
||||
patch->Weld(thresh);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define WELDR_THRESH_CHUNK 0x1010
|
||||
#define WELDR_PATCH_CHUNK 0x1000
|
||||
|
||||
IOResult PVertWeldRecord::Load(ILoad *iload)
|
||||
{
|
||||
IOResult res;
|
||||
ULONG nb;
|
||||
propagate = FALSE;
|
||||
while (IO_OK == (res = iload->OpenChunk()))
|
||||
{
|
||||
switch (iload->CurChunkID())
|
||||
{
|
||||
case WELDR_THRESH_CHUNK:
|
||||
res = iload->Read(&thresh, sizeof(float), &nb);
|
||||
break;
|
||||
// case WELDR_PATCH_CHUNK:
|
||||
// res = oldPatch.Load(iload);
|
||||
// break;
|
||||
}
|
||||
iload->CloseChunk();
|
||||
if (res != IO_OK)
|
||||
return res;
|
||||
}
|
||||
return IO_OK;
|
||||
}
|
@ -1,816 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#define DBGWELD_DUMPx
|
||||
#define DBGWELD_ACTIONx
|
||||
#define DBG_NAMEDSELSx
|
||||
|
||||
#define PROMPT_TIME 2000
|
||||
|
||||
extern int attachReorient;
|
||||
extern float weldThreshold;
|
||||
extern PatchRightMenu pMenu;
|
||||
extern PatchDeleteUser pDel;
|
||||
static int patchDetachCopy = 0;
|
||||
static int patchDetachReorient = 0;
|
||||
;
|
||||
int lockedHandles = 0;
|
||||
HIMAGELIST hFaceImages = NULL;
|
||||
BOOL filterVerts = TRUE;
|
||||
static BOOL filterVecs = TRUE;
|
||||
|
||||
|
||||
static void SetVertFilter()
|
||||
{
|
||||
patchHitLevel[EP_VERTEX] =(filterVerts ? SUBHIT_PATCH_VERTS : 0) |(filterVecs ? SUBHIT_PATCH_VECS : 0);
|
||||
}
|
||||
|
||||
|
||||
extern void CancelEditPatchModes(IObjParam *ip);
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
extern void LoadImages();
|
||||
|
||||
BOOL CALLBACK PatchSelectDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static char string[64];
|
||||
EditPatchMod *ep =(EditPatchMod *)GetWindowLong(hDlg, GWL_USERDATA);
|
||||
ICustToolbar *iToolbar;
|
||||
if (!ep && message != WM_INITDIALOG)
|
||||
return FALSE;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
// Get the module path
|
||||
HMODULE hModule = GetModuleHandle("neleditpatch.dlm");
|
||||
if (hModule)
|
||||
{
|
||||
// Get module file name
|
||||
char moduldeFileName[512];
|
||||
if (GetModuleFileName (hModule, moduldeFileName, 512))
|
||||
{
|
||||
// Get version info size
|
||||
DWORD doomy;
|
||||
uint versionInfoSize=GetFileVersionInfoSize (moduldeFileName, &doomy);
|
||||
if (versionInfoSize)
|
||||
{
|
||||
// Alloc the buffer
|
||||
char *buffer=new char[versionInfoSize];
|
||||
|
||||
// Find the verion resource
|
||||
if (GetFileVersionInfo(moduldeFileName, 0, versionInfoSize, buffer))
|
||||
{
|
||||
uint *versionTab;
|
||||
uint versionSize;
|
||||
if (VerQueryValue (buffer, "\\", (void**)&versionTab, &versionSize))
|
||||
{
|
||||
// Get the pointer on the structure
|
||||
VS_FIXEDFILEINFO *info=(VS_FIXEDFILEINFO*)versionTab;
|
||||
if (info)
|
||||
{
|
||||
// Setup version number
|
||||
char version[512];
|
||||
sprintf (version, "Version %d.%d.%d.%d",
|
||||
info->dwFileVersionMS>>16,
|
||||
info->dwFileVersionMS&0xffff,
|
||||
info->dwFileVersionLS>>16,
|
||||
info->dwFileVersionLS&0xffff);
|
||||
SetWindowText (GetDlgItem (hDlg, IDC_VERSION), version);
|
||||
}
|
||||
else
|
||||
SetWindowText (GetDlgItem (hDlg, IDC_VERSION), "VS_FIXEDFILEINFO * is NULL");
|
||||
}
|
||||
else
|
||||
SetWindowText (GetDlgItem (hDlg, IDC_VERSION), "VerQueryValue failed");
|
||||
}
|
||||
else
|
||||
SetWindowText (GetDlgItem (hDlg, IDC_VERSION), "GetFileVersionInfo failed");
|
||||
|
||||
// Free the buffer
|
||||
delete [] buffer;
|
||||
}
|
||||
else
|
||||
SetWindowText (GetDlgItem (hDlg, IDC_VERSION), "GetFileVersionInfoSize failed");
|
||||
}
|
||||
else
|
||||
SetWindowText (GetDlgItem (hDlg, IDC_VERSION), "GetModuleFileName failed");
|
||||
}
|
||||
else
|
||||
SetWindowText (GetDlgItem (hDlg, IDC_VERSION), "GetModuleHandle failed");
|
||||
|
||||
ep =(EditPatchMod *)lParam;
|
||||
ep->hSelectPanel = hDlg;
|
||||
SetWindowLong(hDlg, GWL_USERDATA, (LONG)ep);
|
||||
// Set up the editing level selector
|
||||
LoadImages();
|
||||
iToolbar = GetICustToolbar(GetDlgItem(hDlg, IDC_SELTYPE));
|
||||
iToolbar->SetImage(hFaceImages);
|
||||
iToolbar->AddTool(ToolButtonItem(CTB_CHECKBUTTON, 0, 4, 0, 4, 24, 23, 24, 23, EP_VERTEX));
|
||||
iToolbar->AddTool(ToolButtonItem(CTB_CHECKBUTTON, 1, 5, 1, 5, 24, 23, 24, 23, EP_EDGE));
|
||||
iToolbar->AddTool(ToolButtonItem(CTB_CHECKBUTTON, 2, 6, 2, 6, 24, 23, 24, 23, EP_PATCH));
|
||||
iToolbar->AddTool(ToolButtonItem(CTB_CHECKBUTTON, 3, 7, 3, 7, 24, 23, 24, 23, EP_TILE));
|
||||
ReleaseICustToolbar(iToolbar);
|
||||
ep->RefreshSelType();
|
||||
CheckDlgButton(hDlg, IDC_DISPLATTICE, ep->displayLattice);
|
||||
// CheckDlgButton( hDlg, IDC_DISPSURFACE, ep->displaySurface);
|
||||
CheckDlgButton(hDlg, IDC_FILTVERTS, filterVerts);
|
||||
CheckDlgButton(hDlg, IDC_FILTVECS, filterVecs);
|
||||
CheckDlgButton(hDlg, IDC_LOCK_HANDLES, lockedHandles);
|
||||
ep->SetSelDlgEnables();
|
||||
|
||||
sprintf(string,"%s - %s",__DATE__,__TIME__);
|
||||
SetDlgItemText(hDlg,ID_VERSION,string);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_DESTROY:
|
||||
// Don't leave in one of our modes!
|
||||
ep->ip->ClearPickMode();
|
||||
CancelEditPatchModes(ep->ip);
|
||||
return FALSE;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_MOUSEMOVE:
|
||||
ep->ip->RollupMouseMessage(hDlg, message, wParam, lParam);
|
||||
return FALSE;
|
||||
|
||||
case WM_COMMAND:
|
||||
{
|
||||
BOOL needRedraw = FALSE;
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case EP_VERTEX:
|
||||
if (ep->GetSubobjectLevel() == EP_VERTEX)
|
||||
ep->ip->SetSubObjectLevel(PO_OBJECT);
|
||||
else ep->ip->SetSubObjectLevel(EP_VERTEX);
|
||||
needRedraw = TRUE;
|
||||
break;
|
||||
|
||||
case EP_EDGE:
|
||||
if (ep->GetSubobjectLevel() == EP_EDGE)
|
||||
ep->ip->SetSubObjectLevel(PO_OBJECT);
|
||||
else ep->ip->SetSubObjectLevel(EP_EDGE);
|
||||
needRedraw = TRUE;
|
||||
break;
|
||||
|
||||
case EP_PATCH:
|
||||
if (ep->GetSubobjectLevel() == EP_PATCH)
|
||||
ep->ip->SetSubObjectLevel(PO_OBJECT);
|
||||
else ep->ip->SetSubObjectLevel(EP_PATCH);
|
||||
needRedraw = TRUE;
|
||||
break;
|
||||
|
||||
case EP_TILE:
|
||||
if (ep->GetSubobjectLevel() == EP_TILE)
|
||||
ep->ip->SetSubObjectLevel(PO_OBJECT);
|
||||
else ep->ip->SetSubObjectLevel(EP_TILE);
|
||||
needRedraw = TRUE;
|
||||
break;
|
||||
|
||||
case IDC_DISPLATTICE:
|
||||
ep->SetDisplayLattice(IsDlgButtonChecked(hDlg, IDC_DISPLATTICE));
|
||||
needRedraw = TRUE;
|
||||
break;
|
||||
case IDC_DISPSURFACE:
|
||||
ep->SetDisplaySurface(IsDlgButtonChecked(hDlg, IDC_DISPSURFACE));
|
||||
needRedraw = TRUE;
|
||||
break;
|
||||
case IDC_FILTVERTS:
|
||||
filterVerts = IsDlgButtonChecked(hDlg, IDC_FILTVERTS);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_FILTVECS), filterVerts ? TRUE : FALSE);
|
||||
SetVertFilter();
|
||||
break;
|
||||
case IDC_FILTVECS:
|
||||
filterVecs = IsDlgButtonChecked(hDlg, IDC_FILTVECS);
|
||||
EnableWindow(GetDlgItem(hDlg, IDC_FILTVERTS), filterVecs ? TRUE : FALSE);
|
||||
SetVertFilter();
|
||||
break;
|
||||
case IDC_LOCK_HANDLES:
|
||||
lockedHandles = IsDlgButtonChecked(hDlg, IDC_LOCK_HANDLES);
|
||||
break;
|
||||
case IDC_NS_COPY:
|
||||
ep->NSCopy();
|
||||
break;
|
||||
case IDC_NS_PASTE:
|
||||
ep->NSPaste();
|
||||
break;
|
||||
}
|
||||
if (needRedraw)
|
||||
{
|
||||
ep->NotifyDependents(FOREVER, PART_DISPLAY, REFMSG_CHANGE);
|
||||
ep->ip->RedrawViews(ep->ip->GetTime(), REDRAW_NORMAL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
if (((LPNMHDR)lParam)->code == TTN_NEEDTEXT)
|
||||
{
|
||||
LPTOOLTIPTEXT lpttt;
|
||||
lpttt =(LPTOOLTIPTEXT)lParam;
|
||||
switch (lpttt->hdr.idFrom)
|
||||
{
|
||||
case EP_VERTEX:
|
||||
lpttt->lpszText = GetString(IDS_TH_VERTEX);
|
||||
break;
|
||||
case EP_EDGE:
|
||||
lpttt->lpszText = GetString(IDS_TH_EDGE);
|
||||
break;
|
||||
case EP_PATCH:
|
||||
lpttt->lpszText = GetString(IDS_TH_PATCH);
|
||||
break;
|
||||
case EP_TILE:
|
||||
lpttt->lpszText = "Tile";
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void EditPatchMod::SetOpsDlgEnables()
|
||||
{
|
||||
if (!hOpsPanel)
|
||||
return;
|
||||
|
||||
nlassert(ip);
|
||||
|
||||
// Disconnect right-click and delete mechanisms
|
||||
ip->GetRightClickMenuManager()->Unregister(&pMenu);
|
||||
ip->UnRegisterDeleteUser(&pDel);
|
||||
|
||||
BOOL oType =(GetSubobjectLevel() == EP_OBJECT) ? TRUE : FALSE;
|
||||
BOOL vType =(GetSubobjectLevel() == EP_VERTEX) ? TRUE : FALSE;
|
||||
BOOL eType =(GetSubobjectLevel() == EP_EDGE) ? TRUE : FALSE;
|
||||
BOOL pType =(GetSubobjectLevel() == EP_PATCH) ? TRUE : FALSE;
|
||||
BOOL tType =(GetSubobjectLevel() == EP_TILE) ? TRUE : FALSE;
|
||||
BOOL epType =(eType || pType) ? TRUE : FALSE;
|
||||
BOOL vepType =(vType || eType || pType) ? TRUE : FALSE;
|
||||
|
||||
|
||||
ICustButton *but;
|
||||
but = GetICustButton(GetDlgItem(hOpsPanel, IDC_BIND));
|
||||
but->Enable(vType);
|
||||
ReleaseICustButton(but);
|
||||
but = GetICustButton(GetDlgItem(hOpsPanel, IDC_UNBIND));
|
||||
but->Enable(vType);
|
||||
ReleaseICustButton(but);
|
||||
|
||||
but = GetICustButton(GetDlgItem(hOpsPanel, IDC_SUBDIVIDE));
|
||||
but->Enable(epType);
|
||||
ReleaseICustButton(but);
|
||||
EnableWindow(GetDlgItem(hOpsPanel, IDC_PROPAGATE), epType);
|
||||
but = GetICustButton(GetDlgItem(hOpsPanel, IDC_ADDTRI));
|
||||
but->Enable(eType);
|
||||
ReleaseICustButton(but);
|
||||
but = GetICustButton(GetDlgItem(hOpsPanel, IDC_ADDQUAD));
|
||||
but->Enable(eType);
|
||||
ReleaseICustButton(but);
|
||||
but = GetICustButton(GetDlgItem(hOpsPanel, IDC_WELD));
|
||||
but->Enable(vType);
|
||||
ReleaseICustButton(but);
|
||||
but = GetICustButton(GetDlgItem(hOpsPanel, IDC_RESET));
|
||||
but->Enable(vType);
|
||||
ReleaseICustButton(but);
|
||||
but = GetICustButton(GetDlgItem(hOpsPanel, IDC_DETACH));
|
||||
but->Enable(pType);
|
||||
ReleaseICustButton(but);
|
||||
EnableWindow(GetDlgItem(hOpsPanel, IDC_DETACHREORIENT), pType);
|
||||
EnableWindow(GetDlgItem(hOpsPanel, IDC_DETACHCOPY), pType);
|
||||
but = GetICustButton(GetDlgItem(hOpsPanel, IDC_PATCH_DELETE));
|
||||
but->Enable(vepType);
|
||||
ReleaseICustButton(but);
|
||||
ISpinnerControl *spin;
|
||||
spin = GetISpinner(GetDlgItem(hOpsPanel, IDC_THRESHSPINNER));
|
||||
spin->Enable(vType);
|
||||
ReleaseISpinner(spin);
|
||||
|
||||
// 3-1-99 watje
|
||||
// 10-4-00 hulud --- bug! :-)
|
||||
but = GetICustButton(GetDlgItem(hOpsPanel, IDC_HIDE));
|
||||
but->Enable(vepType);
|
||||
ReleaseICustButton(but);
|
||||
|
||||
but = GetICustButton(GetDlgItem(hOpsPanel, IDC_UNHIDE));
|
||||
but->Enable(!tType);
|
||||
ReleaseICustButton(but);
|
||||
|
||||
but = GetICustButton(GetDlgItem(hOpsPanel, IDC_EP_EXTRUDE));
|
||||
but->Enable(pType);
|
||||
ReleaseICustButton(but);
|
||||
but = GetICustButton(GetDlgItem(hOpsPanel, IDC_EP_BEVEL));
|
||||
but->Enable(pType);
|
||||
ReleaseICustButton(but);
|
||||
|
||||
but = GetICustButton(GetDlgItem(hOpsPanel, IDC_TURN));
|
||||
but->Enable(pType);
|
||||
ReleaseICustButton(but);
|
||||
|
||||
but = GetICustButton(GetDlgItem(hOpsPanel, IDC_TURN2));
|
||||
but->Enable(pType);
|
||||
ReleaseICustButton(but);
|
||||
|
||||
spin = GetISpinner(GetDlgItem(hOpsPanel, IDC_EP_EXTRUDESPINNER));
|
||||
spin->Enable(pType);
|
||||
ReleaseISpinner(spin);
|
||||
|
||||
spin = GetISpinner(GetDlgItem(hOpsPanel, IDC_EP_OUTLINESPINNER));
|
||||
spin->Enable(pType);
|
||||
ReleaseISpinner(spin);
|
||||
EnableWindow(GetDlgItem(hOpsPanel, IDC_EM_EXTYPE_A), pType);
|
||||
EnableWindow(GetDlgItem(hOpsPanel, IDC_EM_EXTYPE_B), pType);
|
||||
|
||||
EnableWindow(GetDlgItem(hOpsPanel, IDC_EP_SM_SMOOTH4), pType);
|
||||
EnableWindow(GetDlgItem(hOpsPanel, IDC_EP_SM_SMOOTH5), pType);
|
||||
EnableWindow(GetDlgItem(hOpsPanel, IDC_EP_SM_SMOOTH6), pType);
|
||||
|
||||
EnableWindow(GetDlgItem(hOpsPanel, IDC_EP_SM_SMOOTH), pType);
|
||||
EnableWindow(GetDlgItem(hOpsPanel, IDC_EP_SM_SMOOTH2), pType);
|
||||
EnableWindow(GetDlgItem(hOpsPanel, IDC_EP_SM_SMOOTH3), pType);
|
||||
|
||||
// Enable/disable right-click and delete mechanisms
|
||||
if (!oType)
|
||||
{
|
||||
pMenu.SetMod(this);
|
||||
ip->GetRightClickMenuManager()->Register(&pMenu);
|
||||
pDel.SetMod(this);
|
||||
ip->RegisterDeleteUser(&pDel);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
BOOL CALLBACK PatchOpsDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
EditPatchMod *ep =(EditPatchMod *)GetWindowLong(hDlg, GWL_USERDATA);
|
||||
if (!ep && message != WM_INITDIALOG)
|
||||
return FALSE;
|
||||
|
||||
|
||||
ISpinnerControl *spin;
|
||||
ICustButton *ebut;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
ep =(EditPatchMod *)lParam;
|
||||
ep->hOpsPanel = hDlg;
|
||||
for (int i = IDC_SMOOTH_GRP1; i < IDC_SMOOTH_GRP1 + 32; i++)
|
||||
SendMessage(GetDlgItem(hDlg, i), CC_COMMAND, CC_CMD_SET_TYPE, CBT_CHECK);
|
||||
SetWindowLong(hDlg, GWL_USERDATA, (LONG)ep);
|
||||
ICustButton *but = GetICustButton(GetDlgItem(hDlg, IDC_ATTACH));
|
||||
but->SetHighlightColor(GREEN_WASH);
|
||||
but->SetType(CBT_CHECK);
|
||||
ReleaseICustButton(but);
|
||||
CheckDlgButton(hDlg, IDC_ATTACHREORIENT, attachReorient);
|
||||
CheckDlgButton(hDlg, IDC_DETACHCOPY, patchDetachCopy);
|
||||
CheckDlgButton(hDlg, IDC_DETACHREORIENT, patchDetachReorient);
|
||||
CheckDlgButton(hDlg, IDC_PROPAGATE, ep->GetPropagate());
|
||||
ep->stepsSpin = GetISpinner(GetDlgItem(hDlg, IDC_STEPSSPINNER));
|
||||
ep->stepsSpin->SetLimits(0, 100, FALSE);
|
||||
ep->stepsSpin->LinkToEdit(GetDlgItem(hDlg, IDC_STEPS), EDITTYPE_POS_INT);
|
||||
ep->stepsSpin->SetValue(ep->GetMeshSteps(), FALSE);
|
||||
|
||||
// Tile Step
|
||||
ep->tileSpin = GetISpinner(GetDlgItem(hDlg, IDC_TILESTEPSSPINNER));
|
||||
ep->tileSpin->SetLimits(-5, 5, FALSE);
|
||||
ep->tileSpin->LinkToEdit(GetDlgItem(hDlg, IDC_TILESTEPS), EDITTYPE_INT);
|
||||
ep->tileSpin->SetValue(ep->GetTileLevel(), FALSE);
|
||||
|
||||
// Tile Step
|
||||
ep->transitionSpin = GetISpinner(GetDlgItem(hDlg, IDC_TRANSITIONSPINNER));
|
||||
ep->transitionSpin->SetLimits(1, 3, FALSE);
|
||||
ep->transitionSpin->LinkToEdit(GetDlgItem(hDlg, IDC_TRANSITION), EDITTYPE_INT);
|
||||
ep->transitionSpin->SetValue(ep->GetTransitionLevel(), FALSE);
|
||||
|
||||
// 3-18-99 to suport render steps and removal of the mental tesselator
|
||||
ep->stepsRenderSpin = GetISpinner(GetDlgItem(hDlg, IDC_STEPSRENDERSPINNER));
|
||||
ep->stepsRenderSpin->SetLimits(0, 100, FALSE);
|
||||
ep->stepsRenderSpin->LinkToEdit(GetDlgItem(hDlg, IDC_STEPS_RENDER), EDITTYPE_POS_INT);
|
||||
ep->stepsRenderSpin->SetValue(ep->GetMeshStepsRender(), FALSE);
|
||||
CheckDlgButton(hDlg, IDC_TILE_MODE, ep->GetTileMode());
|
||||
CheckDlgButton(hDlg, IDC_SHOW_INTERIOR_FACES, ep->GetShowInterior());
|
||||
CheckDlgButton(hDlg, IDC_KEEP_MAPPING, ep->GetKeepMapping());
|
||||
|
||||
// Old
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_STEPS), !IsDlgButtonChecked(hDlg, IDC_TILE_MODE));
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_STEPSSPINNER), !IsDlgButtonChecked(hDlg, IDC_TILE_MODE));
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_STEPS_RENDER), !IsDlgButtonChecked(hDlg, IDC_TILE_MODE));
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_STEPSRENDERSPINNER), !IsDlgButtonChecked(hDlg, IDC_TILE_MODE));
|
||||
|
||||
// New
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_TILESTEPS), IsDlgButtonChecked(hDlg, IDC_TILE_MODE));
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_TILESTEPSSPINNER), IsDlgButtonChecked(hDlg, IDC_TILE_MODE));
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_KEEP_MAPPING), IsDlgButtonChecked(hDlg, IDC_TILE_MODE));
|
||||
|
||||
// New
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_TRANSITION), IsDlgButtonChecked(hDlg, IDC_TILE_MODE));
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_TRANSITIONSPINNER), IsDlgButtonChecked(hDlg, IDC_TILE_MODE));
|
||||
|
||||
ep->weldSpin = GetISpinner(GetDlgItem(hDlg, IDC_THRESHSPINNER));
|
||||
ep->weldSpin->SetLimits(0, 999999, FALSE);
|
||||
ep->weldSpin->LinkToEdit(GetDlgItem(hDlg, IDC_WELDTHRESH), EDITTYPE_UNIVERSE);
|
||||
ep->weldSpin->SetValue(weldThreshold, FALSE);
|
||||
|
||||
CheckDlgButton(hDlg, IDC_EM_EXTYPE_B, TRUE);
|
||||
CheckDlgButton(hDlg, IDC_EP_SM_SMOOTH, TRUE);
|
||||
CheckDlgButton(hDlg, IDC_EP_SM_SMOOTH4, TRUE);
|
||||
|
||||
ep->inExtrude = FALSE;
|
||||
ep->inBevel = FALSE;
|
||||
|
||||
// Set up spinners
|
||||
spin = GetISpinner(GetDlgItem(hDlg, IDC_EP_EXTRUDESPINNER));
|
||||
spin->SetLimits(-9999999, 9999999, FALSE);
|
||||
spin->LinkToEdit(GetDlgItem(hDlg, IDC_EP_EXTRUDEAMOUNT), EDITTYPE_FLOAT);
|
||||
ReleaseISpinner(spin);
|
||||
|
||||
spin = GetISpinner(GetDlgItem(hDlg, IDC_EP_OUTLINESPINNER));
|
||||
spin->SetLimits(-9999999, 9999999, FALSE);
|
||||
spin->LinkToEdit(GetDlgItem(hDlg, IDC_EP_OUTLINEAMOUNT), EDITTYPE_FLOAT);
|
||||
ReleaseISpinner(spin);
|
||||
|
||||
|
||||
ebut = GetICustButton(GetDlgItem(hDlg, IDC_EP_EXTRUDE));
|
||||
ebut->SetType(CBT_CHECK);
|
||||
ebut->SetHighlightColor(GREEN_WASH);
|
||||
ReleaseICustButton(ebut);
|
||||
|
||||
ebut = GetICustButton(GetDlgItem(hDlg, IDC_EP_BEVEL));
|
||||
ebut->SetType(CBT_CHECK);
|
||||
ebut->SetHighlightColor(GREEN_WASH);
|
||||
ReleaseICustButton(ebut);
|
||||
|
||||
ebut = GetICustButton(GetDlgItem(hDlg, IDC_BIND));
|
||||
ebut->SetType(CBT_CHECK);
|
||||
ebut->SetHighlightColor(GREEN_WASH);
|
||||
ReleaseICustButton(ebut);
|
||||
|
||||
ep->matSpin = SetupIntSpinner(hDlg, IDC_MAT_IDSPIN, IDC_MAT_ID, 1, MAX_MATID, 0);
|
||||
ep->tessUSpin = SetupIntSpinner(hDlg, IDC_TESS_U_SPIN, IDC_TESS_U2, 1, RPO_DEFAULT_TESSEL, 0);
|
||||
ep->tessVSpin = SetupIntSpinner(hDlg, IDC_TESS_V_SPIN, IDC_TESS_V2, 1, RPO_DEFAULT_TESSEL, 0);
|
||||
ep->tileNum = SetupIntSpinner(hDlg, IDC_TILE_MAT_SPIN, IDC_TILE_MAT, 0, 65535, 0);
|
||||
ep->tileRot = SetupIntSpinner(hDlg, IDC_TILE_ROT_SPIN, IDC_TILE_ROT, 0, 3, 0);
|
||||
ep->SetOpsDlgEnables();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_DESTROY:
|
||||
if (ep->weldSpin)
|
||||
{
|
||||
ReleaseISpinner(ep->weldSpin);
|
||||
ep->weldSpin = NULL;
|
||||
}
|
||||
if (ep->stepsSpin)
|
||||
{
|
||||
ReleaseISpinner(ep->stepsSpin);
|
||||
ep->stepsSpin = NULL;
|
||||
}
|
||||
if (ep->tileSpin)
|
||||
{
|
||||
ReleaseISpinner(ep->tileSpin);
|
||||
ep->tileSpin = NULL;
|
||||
}
|
||||
if (ep->transitionSpin)
|
||||
{
|
||||
ReleaseISpinner(ep->transitionSpin);
|
||||
ep->transitionSpin = NULL;
|
||||
}
|
||||
// 3-18-99 to suport render steps and removal of the mental tesselator
|
||||
if (ep->stepsRenderSpin)
|
||||
{
|
||||
ReleaseISpinner(ep->stepsRenderSpin);
|
||||
ep->stepsRenderSpin = NULL;
|
||||
}
|
||||
|
||||
// Don't leave in one of our modes!
|
||||
ep->ip->ClearPickMode();
|
||||
CancelEditPatchModes(ep->ip);
|
||||
ep->ip->UnRegisterDeleteUser(&pDel);
|
||||
ep->ip->GetRightClickMenuManager()->Unregister(&pMenu);
|
||||
return FALSE;
|
||||
|
||||
case CC_SPINNER_CHANGE:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_STEPSSPINNER:
|
||||
ep->SetMeshSteps(ep->stepsSpin->GetIVal());
|
||||
ep->NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
|
||||
ep->ip->RedrawViews(ep->ip->GetTime(), REDRAW_NORMAL);
|
||||
break;
|
||||
case IDC_TILESTEPSSPINNER:
|
||||
ep->SetTileSteps(ep->tileSpin->GetIVal());
|
||||
ep->NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
|
||||
ep->ip->RedrawViews(ep->ip->GetTime(), REDRAW_NORMAL);
|
||||
break;
|
||||
case IDC_TRANSITIONSPINNER:
|
||||
ep->SetTransitionLevel(ep->transitionSpin->GetIVal());
|
||||
ep->NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
|
||||
ep->ip->RedrawViews(ep->ip->GetTime(), REDRAW_NORMAL);
|
||||
break;
|
||||
case IDC_STEPSRENDERSPINNER:
|
||||
ep->SetMeshStepsRender(ep->stepsRenderSpin->GetIVal());
|
||||
break;
|
||||
|
||||
case IDC_THRESHSPINNER:
|
||||
weldThreshold = ep->weldSpin->GetFVal();
|
||||
break;
|
||||
case IDC_EP_EXTRUDESPINNER:
|
||||
{
|
||||
bool enterKey;
|
||||
enterKey = FALSE;
|
||||
if (!HIWORD(wParam) && !ep->inExtrude)
|
||||
{
|
||||
enterKey = TRUE;
|
||||
ep->BeginExtrude(ep->ip->GetTime());
|
||||
}
|
||||
BOOL ln = IsDlgButtonChecked(hDlg, IDC_EM_EXTYPE_B);
|
||||
spin = GetISpinner(GetDlgItem(hDlg, IDC_EP_EXTRUDESPINNER));
|
||||
|
||||
ep->Extrude(ep->ip->GetTime(), spin->GetFVal(), ln);
|
||||
if (enterKey)
|
||||
{
|
||||
ep->EndExtrude(ep->ip->GetTime(), TRUE);
|
||||
spin = GetISpinner(GetDlgItem(hDlg, IDC_EP_EXTRUDESPINNER));
|
||||
if (spin)
|
||||
{
|
||||
spin->SetValue(0, FALSE);
|
||||
ReleaseISpinner(spin);
|
||||
}
|
||||
|
||||
ep->ip->RedrawViews(ep->ip->GetTime(), REDRAW_END);
|
||||
} else
|
||||
{
|
||||
ep->ip->RedrawViews(ep->ip->GetTime(), REDRAW_INTERACTIVE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IDC_EP_OUTLINESPINNER:
|
||||
{
|
||||
bool enterKey;
|
||||
enterKey = FALSE;
|
||||
if (!HIWORD(wParam) && !ep->inBevel)
|
||||
{
|
||||
enterKey = TRUE;
|
||||
ep->BeginBevel(ep->ip->GetTime());
|
||||
}
|
||||
int sm =0;
|
||||
int sm2 = 0;
|
||||
if (IsDlgButtonChecked(hDlg, IDC_EP_SM_SMOOTH))
|
||||
sm = 0;
|
||||
else if (IsDlgButtonChecked(hDlg, IDC_EP_SM_SMOOTH2))
|
||||
sm = 1;
|
||||
else if (IsDlgButtonChecked(hDlg, IDC_EP_SM_SMOOTH3))
|
||||
sm = 2;
|
||||
|
||||
if (IsDlgButtonChecked(hDlg, IDC_EP_SM_SMOOTH4))
|
||||
sm2 = 0;
|
||||
else if (IsDlgButtonChecked(hDlg, IDC_EP_SM_SMOOTH5))
|
||||
sm2 = 1;
|
||||
else if (IsDlgButtonChecked(hDlg, IDC_EP_SM_SMOOTH6))
|
||||
sm2 = 2;
|
||||
|
||||
spin = GetISpinner(GetDlgItem(hDlg, IDC_EP_OUTLINESPINNER));
|
||||
ep->Bevel(ep->ip->GetTime(), spin->GetFVal(), sm, sm2);
|
||||
if (enterKey)
|
||||
{
|
||||
ep->EndBevel(ep->ip->GetTime(), TRUE);
|
||||
spin = GetISpinner(GetDlgItem(hDlg, IDC_EP_OUTLINESPINNER));
|
||||
if (spin)
|
||||
{
|
||||
spin->SetValue(0, FALSE);
|
||||
ReleaseISpinner(spin);
|
||||
}
|
||||
|
||||
ep->ip->RedrawViews(ep->ip->GetTime(), REDRAW_END);
|
||||
} else
|
||||
{
|
||||
ep->ip->RedrawViews(ep->ip->GetTime(), REDRAW_INTERACTIVE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case CC_SPINNER_BUTTONDOWN:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_EP_EXTRUDESPINNER:
|
||||
ep->BeginExtrude(ep->ip->GetTime());
|
||||
break;
|
||||
case IDC_EP_OUTLINESPINNER:
|
||||
ep->BeginBevel(ep->ip->GetTime());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case CC_SPINNER_BUTTONUP:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_EP_EXTRUDESPINNER:
|
||||
ep->EndExtrude(ep->ip->GetTime(), HIWORD(wParam));
|
||||
spin = GetISpinner(GetDlgItem(hDlg, IDC_EP_EXTRUDESPINNER));
|
||||
if (spin)
|
||||
{
|
||||
spin->SetValue(0, FALSE);
|
||||
ReleaseISpinner(spin);
|
||||
}
|
||||
|
||||
ep->ip->RedrawViews(ep->ip->GetTime(), REDRAW_END);
|
||||
break;
|
||||
case IDC_EP_OUTLINESPINNER:
|
||||
ep->EndBevel(ep->ip->GetTime(), HIWORD(wParam));
|
||||
spin = GetISpinner(GetDlgItem(hDlg, IDC_EP_OUTLINESPINNER));
|
||||
if (spin)
|
||||
{
|
||||
spin->SetValue(0, FALSE);
|
||||
ReleaseISpinner(spin);
|
||||
}
|
||||
|
||||
ep->ip->RedrawViews(ep->ip->GetTime(), REDRAW_END);
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_MOUSEMOVE:
|
||||
ep->ip->RollupMouseMessage(hDlg, message, wParam, lParam);
|
||||
return FALSE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
// Subdivision
|
||||
// watje 3-18-99
|
||||
case IDC_SHOW_INTERIOR_FACES:
|
||||
ep->SetShowInterior(IsDlgButtonChecked(hDlg, IDC_SHOW_INTERIOR_FACES));
|
||||
// ep->InvalidateMesh();
|
||||
// ep->NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
|
||||
// ep->ip->RedrawViews (ep->ip->GetTime(),REDRAW_END);
|
||||
break;
|
||||
case IDC_TILE_MODE:
|
||||
{
|
||||
BOOL bCheck=(IsDlgButtonChecked(hDlg, IDC_TILE_MODE)==BST_CHECKED);
|
||||
ep->SetTileMode (bCheck!=0);
|
||||
|
||||
// Old
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_STEPS), !bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_STEPSSPINNER), !bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_STEPS_RENDER), !bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_STEPSRENDERSPINNER), !bCheck);
|
||||
|
||||
// New
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_TILESTEPS), bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_TILESTEPSSPINNER), bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_KEEP_MAPPING), bCheck);
|
||||
|
||||
// New
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_TRANSITION), bCheck);
|
||||
EnableWindow (GetDlgItem (hDlg, IDC_TRANSITIONSPINNER), bCheck);
|
||||
break;
|
||||
}
|
||||
case IDC_KEEP_MAPPING:
|
||||
{
|
||||
ep->SetKeepMapping(IsDlgButtonChecked(hDlg, IDC_KEEP_MAPPING)!=0);
|
||||
break;
|
||||
}
|
||||
// watje 12-10-98
|
||||
case IDC_HIDE:
|
||||
ep->DoHide(ep->GetSubobjectLevel());
|
||||
break;
|
||||
case IDC_UNHIDE:
|
||||
ep->DoUnHide();
|
||||
break;
|
||||
case IDC_BIND:
|
||||
// ep->DoAddHook();
|
||||
if (ep->ip->GetCommandMode() == ep->bindMode)
|
||||
ep->ip->SetStdCommandMode(CID_OBJMOVE);
|
||||
else ep->ip->SetCommandMode(ep->bindMode);
|
||||
break;
|
||||
case IDC_UNBIND:
|
||||
ep->DoRemoveHook();
|
||||
break;
|
||||
// extrude and bevel stuff
|
||||
// watje 12-10-98
|
||||
case IDC_EP_SM_SMOOTH:
|
||||
CheckDlgButton(hDlg, IDC_EP_SM_SMOOTH2, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_EP_SM_SMOOTH3, FALSE);
|
||||
break;
|
||||
case IDC_EP_SM_SMOOTH2:
|
||||
CheckDlgButton(hDlg, IDC_EP_SM_SMOOTH, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_EP_SM_SMOOTH3, FALSE);
|
||||
break;
|
||||
case IDC_EP_SM_SMOOTH3:
|
||||
CheckDlgButton(hDlg, IDC_EP_SM_SMOOTH2, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_EP_SM_SMOOTH, FALSE);
|
||||
break;
|
||||
|
||||
case IDC_EP_SM_SMOOTH4:
|
||||
CheckDlgButton(hDlg, IDC_EP_SM_SMOOTH5, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_EP_SM_SMOOTH6, FALSE);
|
||||
break;
|
||||
case IDC_EP_SM_SMOOTH5:
|
||||
CheckDlgButton(hDlg, IDC_EP_SM_SMOOTH4, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_EP_SM_SMOOTH6, FALSE);
|
||||
break;
|
||||
case IDC_EP_SM_SMOOTH6:
|
||||
CheckDlgButton(hDlg, IDC_EP_SM_SMOOTH4, FALSE);
|
||||
CheckDlgButton(hDlg, IDC_EP_SM_SMOOTH5, FALSE);
|
||||
break;
|
||||
|
||||
|
||||
case IDC_EP_EXTRUDE:
|
||||
if (ep->ip->GetCommandMode() == ep->extrudeMode)
|
||||
ep->ip->SetStdCommandMode(CID_OBJMOVE);
|
||||
else ep->ip->SetCommandMode(ep->extrudeMode);
|
||||
break;
|
||||
case IDC_EP_BEVEL:
|
||||
if (ep->ip->GetCommandMode() == ep->bevelMode)
|
||||
ep->ip->SetStdCommandMode(CID_OBJMOVE);
|
||||
else ep->ip->SetCommandMode(ep->bevelMode);
|
||||
break;
|
||||
|
||||
case IDC_TURN:
|
||||
nlassert (ep->GetSubobjectLevel()==PO_PATCH);
|
||||
ep->DoPatchTurn(true);
|
||||
break;
|
||||
|
||||
case IDC_TURN2:
|
||||
nlassert (ep->GetSubobjectLevel()==PO_PATCH);
|
||||
ep->DoPatchTurn(false);
|
||||
break;
|
||||
|
||||
case IDC_SUBDIVIDE:
|
||||
ep->DoSubdivide(ep->GetSubobjectLevel());
|
||||
break;
|
||||
case IDC_PROPAGATE:
|
||||
ep->SetPropagate(IsDlgButtonChecked(hDlg, IDC_PROPAGATE));
|
||||
break;
|
||||
// Topology
|
||||
case IDC_ADDTRI:
|
||||
if (ep->GetSubobjectLevel() == PO_EDGE)
|
||||
ep->DoPatchAdd(PATCH_TRI);
|
||||
break;
|
||||
case IDC_ADDQUAD:
|
||||
if (ep->GetSubobjectLevel() == PO_EDGE)
|
||||
ep->DoPatchAdd(PATCH_QUAD);
|
||||
break;
|
||||
case IDC_WELD:
|
||||
ep->DoVertWeld();
|
||||
break;
|
||||
case IDC_RESET:
|
||||
ep->DoVertReset();
|
||||
break;
|
||||
case IDC_DETACH:
|
||||
ep->DoPatchDetach(patchDetachCopy, patchDetachReorient);
|
||||
break;
|
||||
case IDC_DETACHCOPY:
|
||||
patchDetachCopy = IsDlgButtonChecked(hDlg, IDC_DETACHCOPY);
|
||||
break;
|
||||
case IDC_DETACHREORIENT:
|
||||
patchDetachReorient = IsDlgButtonChecked(hDlg, IDC_DETACHREORIENT);
|
||||
break;
|
||||
case IDC_ATTACH:
|
||||
{
|
||||
ModContextList mcList;
|
||||
INodeTab nodes;
|
||||
// If the mode is on, turn it off and bail
|
||||
if (ep->ip->GetCommandMode()->ID() == CID_STDPICK)
|
||||
{
|
||||
ep->ip->SetStdCommandMode(CID_OBJMOVE);
|
||||
return FALSE;
|
||||
}
|
||||
// Want to turn on the mode. Make sure we're valid first
|
||||
ep->ip->GetModContexts(mcList, nodes);
|
||||
ep->pickCB.ep = ep;
|
||||
ep->ip->SetPickMode(&ep->pickCB);
|
||||
nodes.DisposeTemporary();
|
||||
break;
|
||||
}
|
||||
case IDC_ATTACHREORIENT:
|
||||
attachReorient = IsDlgButtonChecked(hDlg, IDC_ATTACHREORIENT);
|
||||
break;
|
||||
case IDC_PATCH_DELETE:
|
||||
ep->DoDeleteSelected();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1,120 +0,0 @@
|
||||
/**********************************************************************
|
||||
*<
|
||||
FILE: editsops.cpp
|
||||
|
||||
DESCRIPTION: Edit Shape OSM operations
|
||||
|
||||
CREATED BY: Tom Hudson & Rolf Berteig
|
||||
|
||||
HISTORY: created 25 April, 1995
|
||||
|
||||
*> Copyright (c) 1995, All Rights Reserved.
|
||||
**********************************************************************/
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
|
||||
extern CoreExport Class_ID patchClassID;
|
||||
|
||||
// in mods.cpp
|
||||
extern HINSTANCE hInstance;
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
|
||||
static void XORDottedLine( HWND hwnd, IPoint2 p0, IPoint2 p1 )
|
||||
{
|
||||
HDC hdc;
|
||||
hdc = GetDC( hwnd );
|
||||
SetROP2( hdc, R2_XORPEN );
|
||||
SetBkMode( hdc, TRANSPARENT );
|
||||
SelectObject( hdc, CreatePen( PS_DOT, 0, RGB(255,255,255) ) );
|
||||
MoveToEx( hdc, p0.x, p0.y, NULL );
|
||||
LineTo( hdc, p1.x, p1.y );
|
||||
DeleteObject( SelectObject( hdc, GetStockObject( BLACK_PEN ) ) );
|
||||
ReleaseDC( hwnd, hdc );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
|
||||
EPTempData::~EPTempData()
|
||||
{
|
||||
if (patch) delete patch;
|
||||
if (rpatch) delete rpatch;
|
||||
}
|
||||
|
||||
EPTempData::EPTempData(EditPatchMod *m,EditPatchData *pd)
|
||||
{
|
||||
patch = NULL;
|
||||
rpatch = NULL;
|
||||
patchValid.SetEmpty();
|
||||
patchData = pd;
|
||||
mod = m;
|
||||
}
|
||||
|
||||
void EPTempData::Invalidate(DWORD part,BOOL patchValid)
|
||||
{
|
||||
if ( !patchValid )
|
||||
{
|
||||
delete patch;
|
||||
patch = NULL;
|
||||
delete rpatch;
|
||||
rpatch = NULL;
|
||||
}
|
||||
if ( part & PART_TOPO )
|
||||
{
|
||||
if (rpatch)
|
||||
rpatch->InvalidateChannels (PART_TOPO|PART_GEOM|PART_SELECT|TEXMAP_CHANNEL);
|
||||
}
|
||||
if ( part & PART_GEOM )
|
||||
{
|
||||
if (rpatch)
|
||||
rpatch->InvalidateChannels (PART_GEOM);
|
||||
}
|
||||
if ( part & PART_SELECT )
|
||||
{
|
||||
if (rpatch)
|
||||
rpatch->InvalidateChannels (PART_SELECT);
|
||||
}
|
||||
}
|
||||
|
||||
PatchMesh *EPTempData::GetPatch(TimeValue t, RPatchMesh *&rPatch)
|
||||
{
|
||||
if ( patchValid.InInterval(t) && patch )
|
||||
{
|
||||
rPatch=rpatch;
|
||||
return patch;
|
||||
}
|
||||
else
|
||||
{
|
||||
patchData->SetFlag(EPD_UPDATING_CACHE,TRUE);
|
||||
mod->NotifyDependents(Interval(t,t),
|
||||
PART_GEOM|SELECT_CHANNEL|PART_SUBSEL_TYPE|PART_DISPLAY|PART_TOPO,
|
||||
REFMSG_MOD_EVAL);
|
||||
patchData->SetFlag(EPD_UPDATING_CACHE,FALSE);
|
||||
rPatch=rpatch;
|
||||
return patch;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL EPTempData::PatchCached(TimeValue t)
|
||||
{
|
||||
return (patchValid.InInterval(t) && patch);
|
||||
}
|
||||
|
||||
void EPTempData::UpdateCache(RPO *patchOb)
|
||||
{
|
||||
if ( patch ) delete patch;
|
||||
if ( rpatch ) delete rpatch;
|
||||
patch = new PatchMesh(patchOb->patch);
|
||||
rpatch = new RPatchMesh(*patchOb->rpatch);
|
||||
|
||||
patchValid = FOREVER;
|
||||
|
||||
// These are the channels we care about.
|
||||
patchValid &= patchOb->ChannelValidity(0,GEOM_CHAN_NUM);
|
||||
patchValid &= patchOb->ChannelValidity(0,TOPO_CHAN_NUM);
|
||||
patchValid &= patchOb->ChannelValidity(0,SELECT_CHAN_NUM);
|
||||
patchValid &= patchOb->ChannelValidity(0,SUBSEL_TYPE_CHAN_NUM);
|
||||
patchValid &= patchOb->ChannelValidity(0,DISP_ATTRIB_CHAN_NUM);
|
||||
patchValid &= patchOb->ChannelValidity(0,TEXMAP_CHAN_NUM);
|
||||
}
|
||||
|
@ -1,254 +0,0 @@
|
||||
/**********************************************************************
|
||||
*<
|
||||
FILE: mods.cpp
|
||||
|
||||
DESCRIPTION: DLL implementation of modifiers
|
||||
|
||||
CREATED BY: Rolf Berteig (based on prim.cpp)
|
||||
|
||||
HISTORY: created 30 January 1995
|
||||
|
||||
*> Copyright (c) 1994, All Rights Reserved.
|
||||
**********************************************************************/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "editpat.h"
|
||||
#include "nel/misc/debug.h"
|
||||
|
||||
HINSTANCE hInstance;
|
||||
int controlsInit = FALSE;
|
||||
|
||||
using namespace NLMISC;
|
||||
|
||||
/** public functions **/
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved)
|
||||
{
|
||||
hInstance = hinstDLL;
|
||||
|
||||
if ( !controlsInit )
|
||||
{
|
||||
controlsInit = TRUE;
|
||||
|
||||
// jaguar controls
|
||||
InitCustomControls(hInstance);
|
||||
|
||||
#ifdef OLD3DCONTROLS
|
||||
// initialize 3D controls
|
||||
Ctl3dRegister(hinstDLL);
|
||||
Ctl3dAutoSubclass(hinstDLL);
|
||||
#endif
|
||||
|
||||
// initialize Chicago controls
|
||||
InitCommonControls();
|
||||
}
|
||||
|
||||
switch(fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------
|
||||
// This is the interface to Jaguar:
|
||||
//------------------------------------------------------
|
||||
|
||||
__declspec( dllexport ) const TCHAR *
|
||||
LibDescription()
|
||||
{
|
||||
return "Ryzom patch";
|
||||
}
|
||||
|
||||
|
||||
#ifndef DESIGN_VER
|
||||
|
||||
/// MUST CHANGE THIS NUMBER WHEN ADD NEW CLASS
|
||||
__declspec( dllexport ) int LibNumberClasses() {return 1;}
|
||||
|
||||
__declspec( dllexport ) ClassDesc*
|
||||
LibClassDesc(int i) {
|
||||
switch(i) {
|
||||
case 0: return GetEditPatchModDesc();
|
||||
/*
|
||||
case 0: return GetBendModDesc();
|
||||
case 1: return GetTaperModDesc();
|
||||
case 2: return GetSinWaveObjDesc();
|
||||
case 3: return GetSinWaveModDesc();
|
||||
case 4: return GetEditMeshModDesc();
|
||||
case 5: return GetEditSplineModDesc();
|
||||
case 6: return GetEditPatchModDesc();
|
||||
case 7: return GetTwistModDesc();
|
||||
case 8: return GetExtrudeModDesc();
|
||||
case 9: return GetBombObjDesc();
|
||||
case 10: return GetBombModDesc();
|
||||
case 11: return GetClustModDesc();
|
||||
case 12: return GetSkewModDesc();
|
||||
case 13: return GetNoiseModDesc();
|
||||
case 14: return GetSinWaveOModDesc();
|
||||
case 15: return GetLinWaveObjDesc();
|
||||
case 16: return GetLinWaveModDesc();
|
||||
case 17: return GetLinWaveOModDesc();
|
||||
case 18: return GetOptModDesc();
|
||||
case 19: return GetDispModDesc();
|
||||
case 20: return GetClustNodeModDesc();
|
||||
case 21: return GetGravityObjDesc();
|
||||
case 22: return GetGravityModDesc();
|
||||
case 23: return GetWindObjDesc();
|
||||
case 24: return GetWindModDesc();
|
||||
case 25: return GetDispObjDesc();
|
||||
case 26: return GetDispWSModDesc();
|
||||
case 27: return GetDeflectObjDesc();
|
||||
case 28: return GetDeflectModDesc();
|
||||
case 29: return GetUVWMapModDesc();
|
||||
case 30: return GetSelModDesc();
|
||||
case 31: return GetSmoothModDesc();
|
||||
case 32: return GetMatModDesc();
|
||||
case 33: return GetNormalModDesc();
|
||||
case 34: return GetSurfrevModDesc();
|
||||
case 35: return GetResetXFormDesc();
|
||||
case 36: return GetAFRModDesc();
|
||||
case 37: return GetTessModDesc();
|
||||
case 38: return GetDeleteModDesc();
|
||||
case 39: return GetMeshSelModDesc();
|
||||
case 40: return GetFaceExtrudeModDesc();
|
||||
case 41: return GetUVWXFormModDesc();
|
||||
case 42: return GetMirrorModDesc();
|
||||
case 43: return GetUnwrapModDesc();
|
||||
case 44: return GetBendWSMDesc();
|
||||
case 45: return GetTwistWSMDesc();
|
||||
case 46: return GetTaperWSMDesc();
|
||||
case 47: return GetSkewWSMDesc();
|
||||
case 48: return GetNoiseWSMDesc();
|
||||
case 49: return GetSDeleteModDesc();
|
||||
case 50: return GetDispApproxModDesc();
|
||||
case 51: return GetMeshMesherWSMDesc();
|
||||
case 52: return GetNormalizeSplineDesc();*/
|
||||
default: return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
//
|
||||
// DESIGN VERSION EXCLUDES SOME PLUG_INS
|
||||
//
|
||||
|
||||
/// MUST CHANGE THIS NUMBER WHEN ADD NEW CLASS
|
||||
__declspec( dllexport ) int LibNumberClasses() {return 1;}
|
||||
|
||||
__declspec( dllexport ) ClassDesc*
|
||||
LibClassDesc(int i) {
|
||||
switch(i) {
|
||||
case 0: return GetEditPatchModDesc();
|
||||
/*
|
||||
case 0: return GetBendModDesc();
|
||||
case 1: return GetTaperModDesc();
|
||||
//case 2: return GetSinWaveObjDesc();
|
||||
//case 3: return GetSinWaveModDesc();
|
||||
case 2: return GetEditMeshModDesc();
|
||||
case 3: return GetEditSplineModDesc();
|
||||
case 4: return GetEditPatchModDesc();
|
||||
case 5: return GetTwistModDesc();
|
||||
case 6: return GetExtrudeModDesc();
|
||||
//case 9: return GetBombObjDesc();
|
||||
//case 10: return GetBombModDesc();
|
||||
case 7: return GetClustModDesc();
|
||||
case 8: return GetSkewModDesc();
|
||||
case 9: return GetNoiseModDesc();
|
||||
case 10: return GetSinWaveOModDesc();
|
||||
//case 15: return GetLinWaveObjDesc();
|
||||
//case 16: return GetLinWaveModDesc();
|
||||
case 11: return GetLinWaveOModDesc();
|
||||
case 12: return GetOptModDesc();
|
||||
case 13: return GetDispModDesc();
|
||||
case 14: return GetClustNodeModDesc();
|
||||
//case 21: return GetGravityObjDesc();
|
||||
//case 22: return GetGravityModDesc();
|
||||
//case 23: return GetWindObjDesc();
|
||||
//case 24: return GetWindModDesc();
|
||||
//case 25: return GetDispObjDesc();
|
||||
//case 26: return GetDispWSModDesc();
|
||||
//case 27: return GetDeflectObjDesc();
|
||||
//case 28: return GetDeflectModDesc();
|
||||
case 15: return GetUVWMapModDesc();
|
||||
case 16: return GetSelModDesc();
|
||||
case 17: return GetSmoothModDesc();
|
||||
case 18: return GetMatModDesc();
|
||||
case 19: return GetNormalModDesc();
|
||||
case 20: return GetSurfrevModDesc();
|
||||
case 21: return GetResetXFormDesc();
|
||||
case 22: return GetAFRModDesc();
|
||||
case 23: return GetTessModDesc();
|
||||
case 24: return GetDeleteModDesc();
|
||||
case 25: return GetMeshSelModDesc();
|
||||
case 26: return GetFaceExtrudeModDesc();
|
||||
case 27: return GetUVWXFormModDesc();
|
||||
case 28: return GetMirrorModDesc();
|
||||
// case 29: return GetUnwrapModDesc();
|
||||
case 29: return GetBendWSMDesc();
|
||||
case 30: return GetTwistWSMDesc();
|
||||
case 31: return GetTaperWSMDesc();
|
||||
case 32: return GetSkewWSMDesc();
|
||||
case 33: return GetNoiseWSMDesc();
|
||||
case 34: return GetSDeleteModDesc();
|
||||
case 35: return GetDispApproxModDesc();
|
||||
case 36: return GetMeshMesherWSMDesc();
|
||||
case 37: return GetNormalizeSplineDesc();
|
||||
*/
|
||||
default: return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Return version so can detect obsolete DLLs
|
||||
__declspec( dllexport ) ULONG
|
||||
LibVersion() { return VERSION_3DSMAX; }
|
||||
|
||||
// Let the plug-in register itself for deferred loading
|
||||
__declspec( dllexport ) ULONG CanAutoDefer()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL CALLBACK DefaultSOTProc(
|
||||
HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
|
||||
{
|
||||
IObjParam *ip = (IObjParam*)GetWindowLong(hWnd,GWL_USERDATA);
|
||||
|
||||
switch (msg) {
|
||||
case WM_INITDIALOG:
|
||||
SetWindowLong(hWnd,GWL_USERDATA,lParam);
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_MOUSEMOVE:
|
||||
if (ip) ip->RollupMouseMessage(hWnd,msg,wParam,lParam);
|
||||
return FALSE;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
TCHAR *GetString(int id)
|
||||
{
|
||||
static TCHAR buf[256];
|
||||
|
||||
if (hInstance)
|
||||
return LoadString(hInstance, id, buf, sizeof(buf)) ? buf : NULL;
|
||||
return NULL;
|
||||
}
|
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 838 B |
Before Width: | Height: | Size: 838 B |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 838 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 478 B |
Before Width: | Height: | Size: 478 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 478 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 766 B |
Before Width: | Height: | Size: 766 B |
Before Width: | Height: | Size: 766 B |
@ -1,172 +0,0 @@
|
||||
// Key config file
|
||||
|
||||
/***************
|
||||
*This is the key map: don't touch it.
|
||||
****************/
|
||||
|
||||
Key0 = 48;
|
||||
Key1 = 49;
|
||||
Key2 = 50;
|
||||
Key3 = 51;
|
||||
Key4 = 52;
|
||||
Key5 = 53;
|
||||
Key6 = 54;
|
||||
Key7 = 55;
|
||||
Key8 = 56;
|
||||
Key9 = 57;
|
||||
KeyA = 65;
|
||||
KeyB = 66;
|
||||
KeyC = 67;
|
||||
KeyD = 68;
|
||||
KeyE = 69;
|
||||
KeyF = 70;
|
||||
KeyG = 71;
|
||||
KeyH = 72;
|
||||
KeyI = 73;
|
||||
KeyJ = 74;
|
||||
KeyK = 75;
|
||||
KeyL = 76;
|
||||
KeyM = 77;
|
||||
KeyN = 78;
|
||||
KeyO = 79;
|
||||
KeyP = 80;
|
||||
KeyQ = 81;
|
||||
KeyR = 82;
|
||||
KeyS = 83;
|
||||
KeyT = 84;
|
||||
KeyU = 85;
|
||||
KeyV = 86;
|
||||
KeyW = 87;
|
||||
KeyX = 88;
|
||||
KeyY = 89;
|
||||
KeyZ = 90;
|
||||
KeyLBUTTON = 0x01;
|
||||
KeyRBUTTON = 0x02;
|
||||
KeyCANCEL = 0x03;
|
||||
KeyMBUTTON = 0x04;
|
||||
KeyBACK = 0x08;
|
||||
KeyTAB = 0x09;
|
||||
KeyCLEAR = 0x0C;
|
||||
KeyRETURN = 0x0D;
|
||||
KeySHIFT = 0x10;
|
||||
KeyCONTROL = 0x11;
|
||||
KeyMENU = 0x12;
|
||||
KeyPAUSE = 0x13;
|
||||
KeyCAPITAL = 0x14;
|
||||
KeyKANA = 0x15;
|
||||
KeyHANGEUL = 0x15;
|
||||
KeyHANGUL = 0x15;
|
||||
KeyJUNJA = 0x17;
|
||||
KeyFINAL = 0x18;
|
||||
KeyHANJA = 0x19;
|
||||
KeyKANJI = 0x19;
|
||||
KeyESCAPE = 0x1B;
|
||||
KeyCONVERT = 0x1C;
|
||||
KeyNONCONVERT = 0x1D;
|
||||
KeyACCEPT = 0x1E;
|
||||
KeyMODECHANGE = 0x1F;
|
||||
KeySPACE = 0x20;
|
||||
KeyPRIOR = 0x21;
|
||||
KeyNEXT = 0x22;
|
||||
KeyEND = 0x23;
|
||||
KeyHOME = 0x24;
|
||||
KeyLEFT = 0x25;
|
||||
KeyUP = 0x26;
|
||||
KeyRIGHT = 0x27;
|
||||
KeyDOWN = 0x28;
|
||||
KeySELECT = 0x29;
|
||||
KeyPRINT = 0x2A;
|
||||
KeyEXECUTE = 0x2B;
|
||||
KeySNAPSHOT = 0x2C;
|
||||
KeyINSERT = 0x2D;
|
||||
KeyDELETE = 0x2E;
|
||||
KeyHELP = 0x2F;
|
||||
KeyLWIN = 0x5B;
|
||||
KeyRWIN = 0x5C;
|
||||
KeyAPPS = 0x5D;
|
||||
KeyNUMPAD0 = 0x60;
|
||||
KeyNUMPAD1 = 0x61;
|
||||
KeyNUMPAD2 = 0x62;
|
||||
KeyNUMPAD3 = 0x63;
|
||||
KeyNUMPAD4 = 0x64;
|
||||
KeyNUMPAD5 = 0x65;
|
||||
KeyNUMPAD6 = 0x66;
|
||||
KeyNUMPAD7 = 0x67;
|
||||
KeyNUMPAD8 = 0x68;
|
||||
KeyNUMPAD9 = 0x69;
|
||||
KeyMULTIPLY = 0x6A;
|
||||
KeyADD = 0x6B;
|
||||
KeySEPARATOR = 0x6C;
|
||||
KeySUBTRACT = 0x6D;
|
||||
KeyDECIMAL = 0x6E;
|
||||
KeyDIVIDE = 0x6F;
|
||||
KeyF1 = 0x70;
|
||||
KeyF2 = 0x71;
|
||||
KeyF3 = 0x72;
|
||||
KeyF4 = 0x73;
|
||||
KeyF5 = 0x74;
|
||||
KeyF6 = 0x75;
|
||||
KeyF7 = 0x76;
|
||||
KeyF8 = 0x77;
|
||||
KeyF9 = 0x78;
|
||||
KeyF10 = 0x79;
|
||||
KeyF11 = 0x7A;
|
||||
KeyF12 = 0x7B;
|
||||
KeyF13 = 0x7C;
|
||||
KeyF14 = 0x7D;
|
||||
KeyF15 = 0x7E;
|
||||
KeyF16 = 0x7F;
|
||||
KeyF17 = 0x80;
|
||||
KeyF18 = 0x81;
|
||||
KeyF19 = 0x82;
|
||||
KeyF20 = 0x83;
|
||||
KeyF21 = 0x84;
|
||||
KeyF22 = 0x85;
|
||||
KeyF23 = 0x86;
|
||||
KeyF24 = 0x87;
|
||||
KeyNUMLOCK = 0x90;
|
||||
KeySCROLL = 0x91;
|
||||
KeyLSHIFT = 0xA0;
|
||||
KeyRSHIFT = 0xA1;
|
||||
KeyLCONTROL = 0xA2;
|
||||
KeyRCONTROL = 0xA3;
|
||||
KeyLMENU = 0xA4;
|
||||
KeyRMENU = 0xA5;
|
||||
KeyPROCESSKEY = 0xE5;
|
||||
KeyATTN = 0xF6;
|
||||
KeyCRSEL = 0xF7;
|
||||
KeyEXSEL = 0xF8;
|
||||
KeyEREOF = 0xF9;
|
||||
KeyPLAY = 0xFA;
|
||||
KeyZOOM = 0xFB;
|
||||
KeyNONAME = 0xFC;
|
||||
KeyPA1 = 0xFD;
|
||||
KeyOEM_CLEAR = 0xFE;
|
||||
|
||||
/***************
|
||||
*This is the key assignation: modify here.
|
||||
****************/
|
||||
|
||||
Select = KeySPACE;
|
||||
Pick = KeyP;
|
||||
Fill0 = KeyF5;
|
||||
Fill1 = KeyF6;
|
||||
Fill2 = KeyF7;
|
||||
Fill3 = KeyF8;
|
||||
ModeTile = KeyF1;
|
||||
ModeColor = KeyF2;
|
||||
ModeDisplace = KeyF3;
|
||||
ToggleColor = KeyX;
|
||||
SizeUp = KeyINSERT;
|
||||
SizeDown = KeyDELETE;
|
||||
ToggleTileSize = KeyW;
|
||||
GroupUp = KeyF;
|
||||
GroupDown = KeyV;
|
||||
BackgroundColor = KeyB;
|
||||
ToggleArrows = KeyC;
|
||||
HardnessUp = KeyPRIOR;
|
||||
HardnessDown = KeyNEXT;
|
||||
OpacityUp = KeyHOME;
|
||||
OpacityDown = KeyEND;
|
||||
Zouille = KeyF11;
|
||||
// AutomaticLighting = KeyA;
|
Before Width: | Height: | Size: 16 KiB |
@ -1,148 +0,0 @@
|
||||
/**
|
||||
* Generated by bin2c.exe
|
||||
* binfile: .\light.tga
|
||||
*/
|
||||
|
||||
extern const unsigned char light[];
|
||||
extern const unsigned int lightSize;
|
||||
|
||||
static const unsigned char light[] =
|
||||
{
|
||||
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00,
|
||||
0x20, 0x08, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0xa2, 0xad, 0x00, 0x9c, 0xa6,
|
||||
0xb5, 0x00, 0x9c, 0xa6, 0xb5, 0x00, 0x94, 0xa2,
|
||||
0xad, 0x00, 0x94, 0x9e, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9e,
|
||||
0xad, 0x00, 0x9c, 0xae, 0xbd, 0x0f, 0x9c, 0xb6,
|
||||
0xc6, 0x2c, 0x9c, 0xb2, 0xbd, 0x18, 0x9c, 0xaa,
|
||||
0xbd, 0x08, 0x9c, 0xa6, 0xb5, 0x00, 0x9c, 0xaa,
|
||||
0xb5, 0x02, 0x10, 0x10, 0x10, 0x00, 0x6b, 0x69,
|
||||
0x73, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x9c, 0xaa,
|
||||
0xb5, 0x02, 0x9c, 0xc7, 0xd6, 0x5b, 0x9c, 0xcb,
|
||||
0xde, 0x6e, 0x9c, 0xc7, 0xd6, 0x5f, 0x9c, 0xc3,
|
||||
0xce, 0x4f, 0xa5, 0xba, 0xc6, 0x35, 0x6b, 0x7d,
|
||||
0x84, 0x00, 0x8c, 0x96, 0xa5, 0x00, 0x94, 0x9e,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x8c, 0x96, 0x9c, 0x00, 0x31, 0x2c,
|
||||
0x31, 0xa5, 0x73, 0x7d, 0x84, 0x48, 0x9c, 0xc7,
|
||||
0xd6, 0x5f, 0xa5, 0xe3, 0xef, 0xb5, 0x94, 0xdf,
|
||||
0xe7, 0xa1, 0x9c, 0xe7, 0xef, 0xbe, 0xa5, 0xdb,
|
||||
0xe7, 0x9b, 0x5a, 0x75, 0x84, 0x00, 0x8c, 0xaa,
|
||||
0xb5, 0x00, 0x9c, 0xae, 0xbd, 0x12, 0x94, 0x9e,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x84, 0x86, 0x8c, 0x00, 0x42, 0x28,
|
||||
0x21, 0xd8, 0x52, 0x71, 0x7b, 0xff, 0x5a, 0xe7,
|
||||
0xf7, 0xbe, 0x84, 0xe7, 0xef, 0xbb, 0x9c, 0xeb,
|
||||
0xef, 0xc5, 0x9c, 0xe7, 0xef, 0xbe, 0x52, 0x82,
|
||||
0x8c, 0x00, 0x94, 0xcb, 0xd6, 0x68, 0xa5, 0xcb,
|
||||
0xd6, 0x6b, 0x9c, 0xae, 0xbd, 0x12, 0x94, 0xa2,
|
||||
0xb5, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x7b, 0x7d, 0x84, 0x00, 0x31, 0x20,
|
||||
0x21, 0xd5, 0x84, 0xcf, 0xe7, 0xff, 0x7b, 0xfb,
|
||||
0xff, 0xfe, 0x7b, 0xf3, 0xff, 0xe1, 0x7b, 0xe3,
|
||||
0xef, 0xae, 0x52, 0x8a, 0x94, 0x00, 0x94, 0xe3,
|
||||
0xe7, 0xae, 0xa5, 0xe7, 0xef, 0xbb, 0x9c, 0xc7,
|
||||
0xd6, 0x5f, 0x9c, 0xb6, 0xc6, 0x2c, 0x9c, 0xa6,
|
||||
0xb5, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x73, 0x75, 0x7b, 0x00, 0x4a, 0x34,
|
||||
0x31, 0xff, 0x63, 0xd7, 0xe7, 0xff, 0x94, 0xff,
|
||||
0xff, 0xff, 0x7b, 0xdb, 0xde, 0xcb, 0x42, 0x8e,
|
||||
0x94, 0x00, 0x84, 0xeb, 0xef, 0xc5, 0xa5, 0xeb,
|
||||
0xef, 0xc8, 0x94, 0xdf, 0xe7, 0xa1, 0x9c, 0xcf,
|
||||
0xde, 0x78, 0x9c, 0xba, 0xc6, 0x35, 0x9c, 0xaa,
|
||||
0xb5, 0x02, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9e,
|
||||
0xad, 0x00, 0x21, 0x20, 0x21, 0xf1, 0x94, 0x7d,
|
||||
0x7b, 0xff, 0x73, 0x71, 0x6b, 0xff, 0x52, 0xc3,
|
||||
0xce, 0xff, 0x52, 0xa2, 0xad, 0x28, 0x8c, 0xf3,
|
||||
0xff, 0xe4, 0x7b, 0xf7, 0xff, 0xeb, 0x84, 0xef,
|
||||
0xf7, 0xd1, 0xa5, 0xdf, 0xe7, 0xa5, 0x9c, 0xc3,
|
||||
0xce, 0x4f, 0x9c, 0xae, 0xbd, 0x12, 0x94, 0xa2,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x63, 0x65,
|
||||
0x6b, 0x55, 0x00, 0x04, 0x00, 0xff, 0xb5, 0xaa,
|
||||
0xad, 0xfb, 0xd6, 0xb6, 0xb5, 0xff, 0x84, 0x6d,
|
||||
0x6b, 0xff, 0x63, 0xd3, 0xde, 0xf8, 0x8c, 0xff,
|
||||
0xff, 0xff, 0x84, 0xfb, 0xff, 0xf4, 0x5a, 0xc3,
|
||||
0xd6, 0xb8, 0x94, 0xb2, 0xbd, 0x48, 0x9c, 0xa2,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x73, 0x79, 0x84, 0x88, 0x00, 0x04,
|
||||
0x00, 0xff, 0x42, 0x38, 0x39, 0xff, 0x5a, 0x59,
|
||||
0x5a, 0xff, 0xf7, 0xef, 0xef, 0xff, 0xff, 0xef,
|
||||
0xef, 0xfe, 0xad, 0x9a, 0x9c, 0xff, 0x63, 0x96,
|
||||
0xa5, 0xff, 0x73, 0x82, 0x8c, 0xff, 0x5a, 0x4d,
|
||||
0x52, 0xff, 0x5a, 0x5d, 0x63, 0xff, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x8c, 0x8e,
|
||||
0x9c, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x52, 0x4d,
|
||||
0x4a, 0xff, 0xad, 0xa2, 0xa5, 0xff, 0x9c, 0x92,
|
||||
0x94, 0xfb, 0x6b, 0x65, 0x63, 0xff, 0xb5, 0xa2,
|
||||
0xa5, 0xff, 0xa5, 0x8e, 0x8c, 0xfe, 0x84, 0x65,
|
||||
0x63, 0xf8, 0x4a, 0x3c, 0x39, 0xee, 0x4a, 0x45,
|
||||
0x42, 0xbe, 0x5a, 0x61, 0x63, 0xd1, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xa5, 0x00, 0x08, 0x08,
|
||||
0x08, 0xeb, 0x5a, 0x4d, 0x4a, 0xff, 0xbd, 0xae,
|
||||
0xad, 0xff, 0xf7, 0xe7, 0xe7, 0xff, 0xd6, 0xc3,
|
||||
0xc6, 0xfb, 0x42, 0x38, 0x39, 0xe8, 0x4a, 0x55,
|
||||
0x5a, 0x15, 0x8c, 0x96, 0x9c, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x31, 0x34, 0x39, 0xc8, 0x52, 0x49,
|
||||
0x4a, 0xff, 0xd6, 0xc7, 0xc6, 0xff, 0xff, 0xfb,
|
||||
0xff, 0xff, 0xde, 0xc7, 0xc6, 0xff, 0x52, 0x49,
|
||||
0x4a, 0x7e, 0x84, 0x8a, 0x94, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x84, 0x8a, 0x94, 0xff, 0x8c, 0x7d,
|
||||
0x7b, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xde, 0xcb,
|
||||
0xce, 0xff, 0x52, 0x51, 0x52, 0x2f, 0x94, 0x96,
|
||||
0xa5, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0xfb, 0x8c, 0x92,
|
||||
0x9c, 0xff, 0x6b, 0x65, 0x63, 0xff, 0x7b, 0x79,
|
||||
0x7b, 0xab, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x94, 0x9a, 0xad, 0x00, 0x94, 0x9a,
|
||||
0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x54, 0x52, 0x55, 0x45, 0x56, 0x49,
|
||||
0x53, 0x49, 0x4f, 0x4e, 0x2d, 0x58, 0x46, 0x49,
|
||||
0x4c, 0x45, 0x2e, 0x00,
|
||||
};
|
||||
|
||||
static const unsigned int lightSize = 1068;
|
||||
|
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 838 B |
Before Width: | Height: | Size: 182 B |
Before Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 16 KiB |
@ -1,9 +0,0 @@
|
||||
LIBRARY neleditpatchadv
|
||||
EXPORTS
|
||||
LibDescription @1
|
||||
LibNumberClasses @2
|
||||
LibClassDesc @3
|
||||
LibVersion @4
|
||||
CanAutoDefer @5
|
||||
SECTIONS
|
||||
.data READ WRITE
|
@ -1,124 +0,0 @@
|
||||
/**********************************************************************
|
||||
*<
|
||||
FILE: mods.h
|
||||
|
||||
DESCRIPTION:
|
||||
|
||||
CREATED BY: Rolf Berteig (based on prim.h)
|
||||
|
||||
HISTORY:
|
||||
|
||||
*> Copyright (c) 1994, All Rights Reserved.
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef __MODS__H
|
||||
#define __MODS__H
|
||||
|
||||
#pragma warning (disable : 4786)
|
||||
#include "Max.h"
|
||||
//#include "reslib.h"
|
||||
|
||||
|
||||
TCHAR *GetString(int id);
|
||||
|
||||
/*#define EDITMESH_CLASS_ID 0x00050
|
||||
#define EDITSPLINE_CLASS_ID 0x00060
|
||||
#define EDITPATCH_CLASS_ID 0x00070
|
||||
#define EDITLOFT_CLASS_ID 0x00080
|
||||
|
||||
#define CLUSTOSM_CLASS_ID 0x25215824
|
||||
|
||||
#define RESET_XFORM_CLASS_ID 0x8d562b81
|
||||
#define CLUSTNODEOSM_CLASS_ID 0xc4d33*/
|
||||
|
||||
|
||||
/*extern ClassDesc* GetBombObjDesc();
|
||||
extern ClassDesc* GetBombModDesc();
|
||||
|
||||
extern ClassDesc* GetBendModDesc();
|
||||
extern ClassDesc* GetTaperModDesc();
|
||||
extern ClassDesc* GetSinWaveObjDesc();
|
||||
extern ClassDesc* GetSinWaveModDesc();
|
||||
extern ClassDesc* GetLinWaveObjDesc();
|
||||
extern ClassDesc* GetLinWaveModDesc();
|
||||
extern ClassDesc* GetEditMeshModDesc();
|
||||
extern ClassDesc* GetEditSplineModDesc();*/
|
||||
extern ClassDesc* GetEditPatchModDesc();
|
||||
/*extern ClassDesc* GetTwistModDesc();
|
||||
extern ClassDesc* GetTwistModDesc2();
|
||||
extern ClassDesc* GetExtrudeModDesc();
|
||||
extern ClassDesc* GetClustModDesc();
|
||||
extern ClassDesc* GetSkewModDesc();
|
||||
extern ClassDesc* GetNoiseModDesc();
|
||||
extern ClassDesc* GetSinWaveOModDesc();
|
||||
extern ClassDesc* GetLinWaveOModDesc();
|
||||
extern ClassDesc* GetOptModDesc();
|
||||
extern ClassDesc* GetDispModDesc();
|
||||
extern ClassDesc* GetClustNodeModDesc();
|
||||
extern ClassDesc* GetGravityObjDesc();
|
||||
extern ClassDesc* GetGravityModDesc();
|
||||
extern ClassDesc* GetWindObjDesc();
|
||||
extern ClassDesc* GetWindModDesc();
|
||||
extern ClassDesc* GetDispObjDesc();
|
||||
extern ClassDesc* GetDispWSModDesc();
|
||||
extern ClassDesc* GetDeflectObjDesc();
|
||||
extern ClassDesc* GetDeflectModDesc();
|
||||
extern ClassDesc* GetUVWMapModDesc();
|
||||
extern ClassDesc* GetSelModDesc();
|
||||
extern ClassDesc* GetSmoothModDesc();
|
||||
extern ClassDesc* GetMatModDesc();
|
||||
extern ClassDesc* GetNormalModDesc();
|
||||
extern ClassDesc* GetSurfrevModDesc();
|
||||
extern ClassDesc* GetResetXFormDesc();
|
||||
extern ClassDesc* GetAFRModDesc();
|
||||
extern ClassDesc* GetTessModDesc();
|
||||
extern ClassDesc* GetDeleteModDesc();
|
||||
extern ClassDesc* GetMeshSelModDesc();
|
||||
extern ClassDesc* GetFaceExtrudeModDesc();
|
||||
extern ClassDesc* GetUVWXFormModDesc();
|
||||
extern ClassDesc* GetMirrorModDesc();
|
||||
extern ClassDesc* GetUnwrapModDesc();
|
||||
extern ClassDesc* GetBendWSMDesc();
|
||||
extern ClassDesc* GetTwistWSMDesc();
|
||||
extern ClassDesc* GetTaperWSMDesc();
|
||||
extern ClassDesc* GetSkewWSMDesc();
|
||||
extern ClassDesc* GetNoiseWSMDesc();
|
||||
extern ClassDesc* GetDispApproxModDesc();
|
||||
extern ClassDesc* GetMeshMesherWSMDesc();
|
||||
extern ClassDesc* GetNormalizeSplineDesc();*/
|
||||
|
||||
|
||||
// This is just temporary to make some extra mods so I can
|
||||
// implement the 'more' system in the modify panel.
|
||||
extern ClassDesc* GetBendModDesc2();
|
||||
extern ClassDesc* GetBendModDesc3();
|
||||
extern ClassDesc* GetBendModDesc4();
|
||||
extern ClassDesc* GetBendModDesc5();
|
||||
extern ClassDesc* GetSDeleteModDesc();
|
||||
// in mods.cpp
|
||||
extern HINSTANCE hInstance;
|
||||
|
||||
// For 'Supports Object of Type' rollups
|
||||
extern BOOL CALLBACK DefaultSOTProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
|
||||
|
||||
#define BIGFLOAT float(999999)
|
||||
|
||||
#define NEWSWMCAT _T("Modifiers")
|
||||
|
||||
// Image list used for mesh sub-object toolbar in Edit Mesh, Mesh Select:
|
||||
class MeshSelImageHandler {
|
||||
public:
|
||||
HIMAGELIST images;
|
||||
MeshSelImageHandler () { images = NULL; }
|
||||
~MeshSelImageHandler () { if (images) ImageList_Destroy (images); }
|
||||
HIMAGELIST LoadImages ();
|
||||
};
|
||||
#define IDC_SELVERTEX 0x3260
|
||||
#define IDC_SELEDGE 0x3261
|
||||
#define IDC_SELFACE 0x3262
|
||||
#define IDC_SELPOLY 0x3263
|
||||
#define IDC_SELELEMENT 0x3264
|
||||
extern int *meshSubTypeToolbarIDs;
|
||||
|
||||
#endif
|
||||
|
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 830 B |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 542 B |
@ -1 +0,0 @@
|
||||
#include "stdafx.h"
|
@ -1,11 +0,0 @@
|
||||
#pragma warning (disable : 4786)
|
||||
#include <max.h>
|
||||
#include <decomp.h>
|
||||
#include <buildver.h>
|
||||
#include <iparamb2.h>
|
||||
#include <namesel.h>
|
||||
#include <nsclip.h>
|
||||
#include <sbmtlapi.h>
|
||||
#undef min
|
||||
#undef max
|
||||
|
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.2 KiB |