in UVAtlas/isochart/imtcomputation.cpp [1231:1404]
static HRESULT ComputeIMTOnPixel(
double tempIMT[],
DOUBLEVECTOR2* pUV,
double fTexelLengthW,
double fTexelLengthH,
size_t dwRow,
double* rgvHorizonIntersection,
size_t dwCol,
double* rgvVerticalIntersection,
DOUBLEVECTOR2& leftBottom,
size_t uPrimitiveId,
size_t dwSignalDimension,
LPIMTSIGNALCALLBACK pfnGetSignal,
void* lpTextureData,
double& dPieceArea)
{
HRESULT hr = S_OK;
dPieceArea = 0;
assert(tempIMT != nullptr);
memset(tempIMT, 0, sizeof(double) * IMT_DIM);
DOUBLEVECTOR2 corner[2];
corner[0].x = leftBottom.x + double(dwCol) * fTexelLengthW;
corner[0].y = leftBottom.y + double(dwRow) * fTexelLengthH;
corner[1].x = corner[0].x + fTexelLengthW;
corner[1].y = corner[0].y + fTexelLengthH;
std::vector<DOUBLEVECTOR2> keyPointList;
DOUBLEVECTOR2 p, p1;
// Find the points belong to square and inside the triangle
try
{
for (size_t ii = 0; ii < 2; ii++)
{
double minX = 0, minY = 0, maxX = 0, maxY = 0;
GetBoundOnLine(
rgvHorizonIntersection + (dwRow + ii) * 3,
minX,
maxX);
p.y = corner[ii].y;
for (size_t jj = 0; jj < 2; jj++)
{
p.x = corner[jj].x;
GetBoundOnLine(
rgvVerticalIntersection + (dwCol + jj) * 3,
minY,
maxY);
if (p.x >= minX && p.x <= maxX && p.y >= minY && p.y <= maxY)
{
keyPointList.push_back(p);
}
}
}
// Find all intersection on the pixel boundary
for (size_t ii = 0; ii < 2; ii++)
{
double minX = 0, minY = 0, maxX = 0, maxY = 0;
GetBoundOnLine(
rgvHorizonIntersection + (dwRow + ii) * 3,
minX,
maxX);
GetBoundOnLine(
rgvVerticalIntersection + (dwCol + ii) * 3,
minY,
maxY);
if (minX > corner[0].x&& minX < corner[1].x)
{
p1.x = minX;
p1.y = corner[ii].y;
keyPointList.push_back(p1);
}
if (maxX > corner[0].x&& maxX < corner[1].x)
{
p1.x = maxX;
p1.y = corner[ii].y;
keyPointList.push_back(p1);
}
if (minY > corner[0].y&& minY < corner[1].y)
{
p1.x = corner[ii].x;
p1.y = minY;
keyPointList.push_back(p1);
}
if (maxY > corner[0].y&& maxY < corner[1].y)
{
p1.x = corner[ii].x;
p1.y = maxY;
keyPointList.push_back(p1);
}
}
// Find the points belong to the triangle and inside the square
for (size_t jj = 0; jj < 3; jj++)
{
if (IsPointInSquare(
corner[0], fTexelLengthW, fTexelLengthH, pUV[jj]))
{
keyPointList.push_back(pUV[jj]);
}
}
if (keyPointList.size() < 3)
{
return hr;
}
}
catch (std::bad_alloc&)
{
return E_OUTOFMEMORY;
}
std::vector< DOUBLEVECTOR2 > above;
std::vector< DOUBLEVECTOR2 > below;
FAILURE_RETURN(
GenerateAccumulationLines(
keyPointList,
above,
below));
if (above.size() < 2 || below.size() < 2)
{
return hr;
}
XMFLOAT2 c;
std::unique_ptr<float[]> signalBase(new (std::nothrow) float[dwSignalDimension * sizeof(float) * 4]);
if (!signalBase)
{
return E_OUTOFMEMORY;
}
float* pfSignal = signalBase.get();
for (size_t ii = 0; ii < 2; ii++)
{
c.y = float(corner[ii].y);
for (size_t jj = 0; jj < 2; jj++)
{
c.x = float(corner[jj].x);
hr = pfnGetSignal(
&c,
uPrimitiveId,
dwSignalDimension,
lpTextureData,
pfSignal);
if (FAILED(hr))
{
return hr;
}
pfSignal += dwSignalDimension;
}
}
hr = Accumulation(
corner,
signalBase.get(),
dwSignalDimension,
above,
below,
tempIMT,
dPieceArea);
return hr;
}