Removed: #1440 Duplicate project

--HG--
branch : build_pipeline_v3
hg/feature/build_pipeline_v3
kaetemi 12 years ago
parent 4cc4eb431f
commit 5e1cab83f5

@ -4,7 +4,6 @@ ADD_SUBDIRECTORY(nel_patch_converter)
ADD_SUBDIRECTORY(nel_3dsmax_shared) ADD_SUBDIRECTORY(nel_3dsmax_shared)
ADD_SUBDIRECTORY(nel_export) ADD_SUBDIRECTORY(nel_export)
ADD_SUBDIRECTORY(nel_patch_edit) ADD_SUBDIRECTORY(nel_patch_edit)
ADD_SUBDIRECTORY(nel_patch_edit_adv)
ADD_SUBDIRECTORY(nel_patch_paint) ADD_SUBDIRECTORY(nel_patch_paint)
ADD_SUBDIRECTORY(nel_vertex_tree_paint) ADD_SUBDIRECTORY(nel_vertex_tree_paint)
ADD_SUBDIRECTORY(tile_utility) ADD_SUBDIRECTORY(tile_utility)

Binary file not shown.

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)

Binary file not shown.

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(&copy, 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;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 838 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 838 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 838 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

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;

File diff suppressed because it is too large Load Diff

Binary file not shown.

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;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 838 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 830 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 542 B

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save