static HRESULT ComputeIMTOnPixel()

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;
    }