302 lines
7.3 KiB
C++
302 lines
7.3 KiB
C++
|
#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;
|
||
|
}
|
||
|
|
||
|
|