khanat-opennel-code/code/nel/tools/3d/plugin_max/nel_patch_edit/np_epm_material.cpp
2010-05-06 02:08:41 +02:00

1148 lines
29 KiB
C++

#include "stdafx.h"
#include "editpat.h"
// ------------------------------------------------------------------------------------------------------------------------------------------------------
#define DBGWELD_DUMPx
#define DBGWELD_ACTIONx
#define DBG_NAMEDSELSx
#define PROMPT_TIME 2000
// ------------------------------------------------------------------------------------------------------------------------------------------------------
int EditPatchMod::GetSelMatIndex()
{
ModContextList mcList;
INodeTab nodes;
BOOL first = 1;
int mat=-1;
if (!ip)
return -1;
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;
mat =(int)patch->getPatchMtlIndex(j);
} else
{
if ((int)patch->getPatchMtlIndex(j) != mat)
{
return -1;
}
}
}
}
}
nodes.DisposeTemporary();
return mat;
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------
void EditPatchMod::SetSelMatIndex(int index)
{
ModContextList mcList;
INodeTab nodes;
BOOL holdNeeded = FALSE;
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;
BOOL altered = FALSE;
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 PatchRestore(patchData, this, patch, rpatch, "SetSelMatIndex"));
}
for (int j = 0; j < patch->getNumPatches(); j++)
{
if (patch->patchSel[j])
{
altered = holdNeeded = TRUE;
patch->setPatchMtlIndex(j, (MtlID)index);
}
}
if (altered)
{
patchData->UpdateChanges(patch, rpatch, FALSE);
patchData->TempData(this)->Invalidate(PART_TOPO);
}
patchData->SetFlag(EPD_BEENDONE, TRUE);
}
if (holdNeeded)
theHold.Accept(GetString(IDS_TH_PATCHMTLCHANGE));
else
{
ip->DisplayTempPrompt(GetString(IDS_TH_NOPATCHESSEL), PROMPT_TIME);
theHold.End();
}
nodes.DisposeTemporary();
InvalidateSurfaceUI();
NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
ip->RedrawViews(ip->GetTime());
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------
int EditPatchMod::GetSelTessU()
{
ModContextList mcList;
INodeTab nodes;
BOOL first = 1;
int mat=-1;
if (!ip)
return -1;
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;
mat = (int)rpatch->getUIPatch (j).NbTilesU;
}
else
{
if ((int)rpatch->getUIPatch (j).NbTilesU != mat)
{
return -1;
}
}
}
}
}
nodes.DisposeTemporary();
return mat;
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------
int EditPatchMod::GetSelTessV()
{
ModContextList mcList;
INodeTab nodes;
BOOL first = 1;
int mat=-1;
if (!ip)
return -1;
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;
mat = (int)rpatch->getUIPatch (j).NbTilesV;
}
else
{
if ((int)rpatch->getUIPatch (j).NbTilesV != mat)
{
return -1;
}
}
}
}
}
nodes.DisposeTemporary();
return mat;
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------
void EditPatchMod::SetSelTess(int nU, int nV)
{
ModContextList mcList;
INodeTab nodes;
BOOL holdNeeded = FALSE;
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;
BOOL altered = FALSE;
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 PatchRestore(patchData, this, patch, rpatch, "SetSelTess"));
}
for (int j = 0; j < patch->getNumPatches(); j++)
{
if (patch->patchSel[j])
{
altered = holdNeeded = TRUE;
rpatch->getUIPatch (j).Init (nU, nV, true);
}
}
if (altered)
{
patchData->UpdateChanges(patch, rpatch, FALSE);
patchData->TempData(this)->Invalidate(PART_TOPO);
}
patchData->SetFlag(EPD_BEENDONE, TRUE);
}
if (holdNeeded)
theHold.Accept("Tile count in U and V change");
else
{
ip->DisplayTempPrompt(GetString(IDS_TH_NOPATCHESSEL), PROMPT_TIME);
theHold.End();
}
nodes.DisposeTemporary();
InvalidateSurfaceUI();
NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
ip->RedrawViews(ip->GetTime());
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------
int EditPatchMod::getSmoothFlags ()
{
ModContextList mcList;
INodeTab nodes;
bool notFlagged=false;
bool flagged=false;
if (!ip)
return -1;
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 each edges
for (int j = 0; j < patch->getNumEdges(); j++)
{
// Is edge selected
if (patch->edgeSel[j])
{
// Patch num
#if (MAX_RELEASE < 4000)
int p0=patch->edges[j].patch1;
int p1=patch->edges[j].patch2;
bool edgeFlag = ((p0!=-1)&&(rpatch->getUIPatch (p0).getEdgeFlag (WhereIsTheEdge (p0, j, *patch)))) ||
((p1!=-1)&&(rpatch->getUIPatch (p1).getEdgeFlag (WhereIsTheEdge (p1, j, *patch))));
#else // (MAX_RELEASE < 4000)
bool edgeFlag = false;
for (int pn = 0; pn < patch->edges[j].patches.Count(); ++pn)
{
int p = patch->edges[j].patches[pn];
if (rpatch->getUIPatch(p).getEdgeFlag(WhereIsTheEdge(p, j, *patch)))
{
edgeFlag = true;
break;
}
}
#endif // (MAX_RELEASE < 4000)
// Is edge flaged ?
if (edgeFlag)
{
// Flagged !
flagged=true;
}
else
{
// Not flagged !
notFlagged=true;
}
}
}
}
nodes.DisposeTemporary();
return flagged?(notFlagged?2:1):0;
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------
void EditPatchMod::setSmoothFlags (bool smooth)
{
ModContextList mcList;
INodeTab nodes;
BOOL holdNeeded = FALSE;
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;
BOOL altered = FALSE;
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 PatchRestore(patchData, this, patch, rpatch, "SetSmoothFlags"));
}
// For each edges
for (int j = 0; j < patch->getNumEdges(); j++)
{
// Is edge selected
if (patch->edgeSel[j])
{
#if (MAX_RELEASE < 4000)
// Patch num
int p0=patch->edges[j].patch1;
int p1=patch->edges[j].patch2;
// Patch exist ?
if (p0!=-1)
{
// Set the flag
rpatch->getUIPatch (p0).setEdgeFlag (WhereIsTheEdge (p0, j, *patch), smooth);
// Touched
altered=TRUE;
holdNeeded=TRUE;
}
// idem patch #2
if (p1!=-1)
{
// Set the flag
rpatch->getUIPatch (p1).setEdgeFlag (WhereIsTheEdge (p1, j, *patch), smooth);
// Touched
altered=TRUE;
holdNeeded=TRUE;
}
#else // (MAX_RELEASE < 4000)
for (int pe = 0; pe < patch->edges[j].patches.Count(); ++pe)
{
int pn = patch->edges[j].patches[pe];
// Set the flag
rpatch->getUIPatch(pn).setEdgeFlag(WhereIsTheEdge(pn, j, *patch), smooth);
// Touched
altered=TRUE;
holdNeeded=TRUE;
}
#endif // (MAX_RELEASE < 4000)
}
}
// If touched
if (altered)
{
patchData->UpdateChanges(patch, rpatch, FALSE);
patchData->TempData(this)->Invalidate(PART_TOPO);
}
patchData->SetFlag(EPD_BEENDONE, TRUE);
}
if (holdNeeded)
theHold.Accept("Tile count in U and V change");
else
{
ip->DisplayTempPrompt(GetString(IDS_TH_NOPATCHESSEL), PROMPT_TIME);
theHold.End();
}
nodes.DisposeTemporary();
InvalidateEdgeUI();
NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
ip->RedrawViews(ip->GetTime());
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------
void EditPatchMod::BalanceSelPatch (int patch, int size, bool balanceU, std::set<int>& visitedU, std::set<int>& visitedV, RPatchMesh* rpatch, PatchMesh *ppatch)
{
// already visited ?
if ((balanceU&&(visitedU.find(patch)!=visitedU.end()))||((!balanceU)&&(visitedV.find(patch)!=visitedV.end())))
return;
// insert in the visit set
if (balanceU)
visitedU.insert (patch);
else
visitedV.insert (patch);
// Get patch tess level..
int nU=rpatch->getUIPatch (patch).NbTilesU;
int nV=rpatch->getUIPatch (patch).NbTilesV;
if (balanceU)
nU=size;
else
nV=size;
// Resize the patch
rpatch->getUIPatch (patch).Init (nU, nV, true);
// Call neiborhood
for (int i=0; i<4; i++)
{
int nEdge=ppatch->patches[patch].edge[i];
#if (MAX_RELEASE < 4000)
int nOtherPatch=(ppatch->edges[nEdge].patch1==patch)?ppatch->edges[nEdge].patch2:ppatch->edges[nEdge].patch1;
#else // (MAX_RELEASE < 4000)
int nOtherPatch = (ppatch->edges[nEdge].patches.Count() > 0 && ppatch->edges[nEdge].patches[0] == patch)
? (ppatch->edges[nEdge].patches.Count() > 1 ? ppatch->edges[nEdge].patches[1] : -1)
: (ppatch->edges[nEdge].patches.Count() > 0 ? ppatch->edges[nEdge].patches[0] : -1);
#endif // (MAX_RELEASE < 4000)
if (nOtherPatch>=0)
{
int nNeiborEdge=WhereIsTheEdge (nOtherPatch, nEdge, *ppatch);
BalanceSelPatch (nOtherPatch, (i&1)?nU:nV, (nNeiborEdge&1)!=0, visitedU, visitedV, rpatch, ppatch);
}
}
}
void EditPatchMod::BalanceSelPatch ()
{
ModContextList mcList;
INodeTab nodes;
BOOL holdNeeded = FALSE;
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;
BOOL altered = FALSE;
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 PatchRestore(patchData, this, patch, rpatch, "SetSelTess"));
}
std::set<int> visitedU;
std::set<int> visitedV;
for (int j = 0; j < patch->getNumPatches(); j++)
{
if (patch->patchSel[j])
{
altered = holdNeeded = TRUE;
// insert it
visitedU.insert (j);
visitedV.insert (j);
// Get patch tess level..
int nU=rpatch->getUIPatch (j).NbTilesU;
int nV=rpatch->getUIPatch (j).NbTilesV;
// Call neiborhood
for (int i=0; i<4; i++)
{
int nEdge=patch->patches[j].edge[i];
#if (MAX_RELEASE < 4000)
int nOtherPatch=(patch->edges[nEdge].patch1==j)?patch->edges[nEdge].patch2:patch->edges[nEdge].patch1;
#else // (MAX_RELEASE < 4000)
int nOtherPatch = (patch->edges[nEdge].patches.Count() > 0 && patch->edges[nEdge].patches[0] == j)
? (patch->edges[nEdge].patches.Count() > 1 ? patch->edges[nEdge].patches[1] : -1)
: (patch->edges[nEdge].patches.Count() > 0 ? patch->edges[nEdge].patches[0] : -1);
#endif // (MAX_RELEASE < 4000)
if (nOtherPatch>=0)
{
int nNeiborEdge=WhereIsTheEdge (nOtherPatch, nEdge, *patch);
BalanceSelPatch (nOtherPatch, (i&1)?nU:nV, (nNeiborEdge&1)!=0, visitedU, visitedV, rpatch, patch);
}
}
}
}
if (altered)
{
patchData->UpdateChanges(patch, rpatch, FALSE);
patchData->TempData(this)->Invalidate(PART_TOPO);
}
patchData->SetFlag(EPD_BEENDONE, TRUE);
}
if (holdNeeded)
theHold.Accept("Balance tile");
else
{
ip->DisplayTempPrompt(GetString(IDS_TH_NOPATCHESSEL), PROMPT_TIME);
theHold.End();
}
nodes.DisposeTemporary();
InvalidateSurfaceUI();
NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
ip->RedrawViews(ip->GetTime());
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------
/*void EditPatchMod::SetTileNum (ULONG nU)
{
ModContextList mcList;
INodeTab nodes;
BOOL holdNeeded = FALSE;
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;
BOOL altered = FALSE;
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 PatchRestore(patchData, this, patch, rpatch, "SetTileNum"));
}
nlassert (patch->numPatches==(int)rpatch->UIPatch.size());
for (int j = 0; j < patch->getNumPatches(); j++)
{
int nTileU=1<<rpatch->UIPatch[j].NbTilesU;
int nTileV=1<<rpatch->UIPatch[j].NbTilesV;
for (int v = 0; v < nTileV; v++)
for (int u= 0; u < nTileU; u++)
{
if (rpatch->tileSel[rpatch->GetTileNumber(j, u, v)])
{
altered = holdNeeded = TRUE;
rpatch->UIPatch[j].Tile[u+v*nTileU].MatID = nU;
}
}
}
if (altered)
{
patchData->UpdateChanges(patch, rpatch, FALSE);
patchData->TempData(this)->Invalidate(PART_TOPO);
}
patchData->SetFlag(EPD_BEENDONE, TRUE);
}
if (holdNeeded)
theHold.Accept("Tile number change");
else
{
ip->DisplayTempPrompt("No tile selected", PROMPT_TIME);
theHold.End();
}
nodes.DisposeTemporary();
InvalidateSurfaceUI();
NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
ip->RedrawViews(ip->GetTime());
}*/
// ------------------------------------------------------------------------------------------------------------------------------------------------------
/*ULONG EditPatchMod::GetTileNum ()
{
ModContextList mcList;
INodeTab nodes;
BOOL first = 1;
ULONG num=0xffffffff;
if (!ip)
return -1;
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;
nlassert (patch->numPatches==(int)rpatch->UIPatch.size());
for (int j = 0; j < patch->getNumPatches(); j++)
{
int nTileU=1<<rpatch->UIPatch[j].NbTilesU;
int nTileV=1<<rpatch->UIPatch[j].NbTilesV;
for (int v = 0; v < nTileV; v++)
for (int u= 0; u < nTileU; u++)
{
if (rpatch->tileSel[rpatch->GetTileNumber(j, u, v)])
{
if (first)
{
first = FALSE;
num = rpatch->UIPatch[j].Tile[u+v*nTileU].MatID;
}
else
{
if (rpatch->UIPatch[j].Tile[u+v*nTileU].MatID != num)
{
return 0xffffffff;
}
}
}
}
}
}
nodes.DisposeTemporary();
return num;
}*/
// ------------------------------------------------------------------------------------------------------------------------------------------------------
/*void EditPatchMod::SetTileRot (int nRot)
{
ModContextList mcList;
INodeTab nodes;
BOOL holdNeeded = FALSE;
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;
BOOL altered = FALSE;
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 PatchRestore(patchData, this, patch, rpatch, "SetTileRot"));
}
nlassert (patch->numPatches==(int)rpatch->UIPatch.size());
for (int j = 0; j < patch->getNumPatches(); j++)
{
int nTileU=1<<rpatch->UIPatch[j].NbTilesU;
int nTileV=1<<rpatch->UIPatch[j].NbTilesV;
for (int v = 0; v < nTileV; v++)
for (int u= 0; u < nTileU; u++)
{
if (rpatch->tileSel[rpatch->GetTileNumber(j, u, v)])
{
altered = holdNeeded = TRUE;
rpatch->UIPatch[j].Tile[u+v*nTileU].Rotate = nRot;
}
}
}
if (altered)
{
patchData->UpdateChanges(patch, rpatch, FALSE);
patchData->TempData(this)->Invalidate(PART_TOPO);
}
patchData->SetFlag(EPD_BEENDONE, TRUE);
}
if (holdNeeded)
theHold.Accept("Tile rotation change");
else
{
ip->DisplayTempPrompt("No tile selected", PROMPT_TIME);
theHold.End();
}
nodes.DisposeTemporary();
InvalidateSurfaceUI();
NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
ip->RedrawViews(ip->GetTime());
}*/
// ------------------------------------------------------------------------------------------------------------------------------------------------------
/*int EditPatchMod::GetTileRot ()
{
ModContextList mcList;
INodeTab nodes;
BOOL first = 1;
int rot=-1;
if (!ip)
return -1;
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;
nlassert (patch->numPatches==(int)rpatch->UIPatch.size());
for (int j = 0; j < patch->getNumPatches(); j++)
{
int nTileU=1<<rpatch->UIPatch[j].NbTilesU;
int nTileV=1<<rpatch->UIPatch[j].NbTilesV;
for (int v = 0; v < nTileV; v++)
for (int u= 0; u < nTileU; u++)
{
if (rpatch->tileSel[rpatch->GetTileNumber(j, u, v)])
{
if (first)
{
first = FALSE;
rot = rpatch->UIPatch[j].Tile[u+v*nTileU].Rotate;
}
else
{
if (rpatch->UIPatch[j].Tile[u+v*nTileU].Rotate != rot)
{
return -1;
}
}
}
}
}
}
nodes.DisposeTemporary();
return rot;
}*/
// ------------------------------------------------------------------------------------------------------------------------------------------------------
void EditPatchMod::SelectByMat(int index, 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->getPatchMtlIndex(j) == index)
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_SELECTBYMATID));
nodes.DisposeTemporary();
NotifyDependents(FOREVER, PART_SELECT, REFMSG_CHANGE);
ip->RedrawViews(ip->GetTime());
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------
MtlID EditPatchMod::GetNextAvailMtlID(ModContext* mc)
{
if (!mc)
return 1;
EditPatchData *patchData =(EditPatchData*)mc->localData;
if (!patchData)
return 1;
// If the mesh isn't yet cache, this will cause it to get cached.
RPatchMesh *rpatch;
PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch);
if (!patch)
return 1;
int mtlID = GetSelFaceUniqueMtlID(mc);
if (mtlID == -1)
{
int i;
MtlID min, max;
BOOL first = TRUE;
int p;
for (p = 0; p < patch->numPatches; ++p)
{
MtlID thisID = patch->getPatchMtlIndex(p);
if (first)
{
min = max = thisID;
first = FALSE;
}
else
if (thisID < min)
min = thisID;
else
if (thisID > max)
max = thisID;
}
// If room below, return it
if (min > 0)
return min - 1;
// Build a bit array to find any gaps
BitArray b;
int bits = max - min + 1;
b.SetSize(bits);
b.ClearAll();
for (p = 0; p < patch->numPatches; ++p)
b.Set(patch->getPatchMtlIndex(p) - min);
for (i = 0; i < bits; ++i)
{
if (!b[i])
return (MtlID)(i + min);
}
// No gaps! If room above, return it
if (max < 65535)
return max + 1;
}
return (MtlID)mtlID;
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------
BOOL EditPatchMod::HasFaceSelection(ModContext* mc)
{
// Are we the edited object?
if (ip == NULL)
return FALSE;
EditPatchData *patchData =(EditPatchData*)mc->localData;
if (!patchData)
return FALSE;
// If the mesh isn't yet cache, this will cause it to get cached.
RPatchMesh *rpatch;
PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch);
if (!patch)
return FALSE;
// Is Patch selection active?
if (selLevel == EP_PATCH && patch->patchSel.NumberSet())
return TRUE;
return FALSE;
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------
void EditPatchMod::SetSelFaceMtlID(ModContext* mc, MtlID id, BOOL bResetUnsel)
{
int altered = 0;
EditPatchData *patchData =(EditPatchData*)mc->localData;
if (!patchData)
return;
// If the mesh isn't yet cache, this will cause it to get cached.
RPatchMesh *rpatch;
PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch);
if (!patch)
return;
// If this is the first edit, then the delta arrays will be allocated
patchData->BeginEdit(ip->GetTime());
if (theHold.Holding())
theHold.Put(new PatchRestore(patchData, this, patch, rpatch));
for (int p = 0; p < patch->numPatches; ++p)
{
if (patch->patchSel[p])
{
altered = TRUE;
patch->setPatchMtlIndex(p, id);
}
}
if (altered)
{
patchData->UpdateChanges(patch, rpatch, FALSE);
InvalidateSurfaceUI();
}
NotifyDependents(FOREVER, PART_TOPO, REFMSG_CHANGE);
ip->RedrawViews(ip->GetTime());
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------
int EditPatchMod::GetSelFaceUniqueMtlID(ModContext* mc)
{
int mtlID;
mtlID = GetSelFaceAnyMtlID(mc);
if (mtlID == -1)
return mtlID;
EditPatchData *patchData =(EditPatchData*)mc->localData;
if (!patchData)
return 1;
// If the mesh isn't yet cache, this will cause it to get cached.
RPatchMesh *rpatch;
PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch);
if (!patch)
return 1;
for (int p = 0; p < patch->numPatches; ++p)
{
if (patch->patchSel[p])
continue;
if (patch->getPatchMtlIndex(p) != mtlID)
continue;
mtlID = -1;
}
return mtlID;
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------
int EditPatchMod::GetSelFaceAnyMtlID(ModContext* mc)
{
int mtlID = -1;
BOOL bGotFirst = FALSE;
EditPatchData *patchData =(EditPatchData*)mc->localData;
if (!patchData)
return 1;
// If the mesh isn't yet cache, this will cause it to get cached.
RPatchMesh *rpatch;
PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch);
if (!patch)
return 1;
for (int p = 0; p < patch->numPatches; ++p)
{
if (!patch->patchSel[p])
continue;
if (bGotFirst)
{
if (mtlID != patch->getPatchMtlIndex(p))
{
mtlID = -1;
break;
}
}
else
{
mtlID = patch->getPatchMtlIndex(p);
bGotFirst = TRUE;
}
}
return mtlID;
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------
int EditPatchMod::GetMaxMtlID(ModContext* mc)
{
MtlID mtlID = 0;
EditPatchData *patchData =(EditPatchData*)mc->localData;
if (!patchData)
return 1;
// If the mesh isn't yet cache, this will cause it to get cached.
RPatchMesh *rpatch;
PatchMesh *patch = patchData->TempData(this)->GetPatch(ip->GetTime(), rpatch);
if (!patch)
return 1;
for (int p = 0; p < patch->numPatches; ++p)
mtlID = std::max(mtlID, patch->getPatchMtlIndex(p));
return mtlID;
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------