Пример #1
0
//-------------------------------------------------------------------------------------
HRESULT CIsochartMesh::InitializeLSCMEquation(
    CSparseMatrix<double>& A,
    CVector<double>& B,
    CVector<double>& U,
    uint32_t dwBaseVertId1,
    uint32_t dwBaseVertId2)
{
    HRESULT hr = S_OK;
    CSparseMatrix<double> orgA;
    CSparseMatrix<double> M;
    CVector<double> orgB;

    if (!orgA.resize(2*m_dwFaceNumber, (m_dwVertNumber-2)*2))
    {
        return E_OUTOFMEMORY;
    }
    if (!M.resize(2*m_dwFaceNumber, 2*2))
    {
        return E_OUTOFMEMORY;
    }
    
    for (uint32_t ii=0; ii<m_dwFaceNumber; ii++)
    {
        FAILURE_RETURN(
            AddFaceWeight(ii, orgA, M, dwBaseVertId1, dwBaseVertId2));
    }

    // b = -M*u
    if (!CSparseMatrix<double>::Mat_Mul_Vec(orgB, M, U))
    {
        return E_OUTOFMEMORY;
    }
    assert(orgB.size() == 2*m_dwFaceNumber);
    CVector<double>::scale(orgB, orgB, static_cast<double>(-1));

    // A' = A^T * A
    if (!CSparseMatrix<double>::Mat_Trans_MUL_Mat(A, orgA))
    {
        return E_OUTOFMEMORY;
    }

    // B' = A^T * b
    if (!CSparseMatrix<double>::Mat_Trans_Mul_Vec(B, orgA, orgB))
    {
        return E_OUTOFMEMORY;
    }
    
    return hr;
}
HRESULT CIsochartMesh::InitializeBarycentricEquation(
    CSparseMatrix<double>& A,
    CVector<double>& BU,
    CVector<double>& BV,
    const std::vector<double>& boundTable,
    const std::vector<uint32_t>& vertMap)
{
    HRESULT hr = S_OK;

    CSparseMatrix<double> orgA;
    CVector<double> orgBU, orgBV;

    // 1. Allocate memory
    size_t dwOrgADim = m_dwVertNumber - boundTable.size()/2;

    try
    {
        orgA.resize(dwOrgADim, dwOrgADim);
        orgBU.resize(dwOrgADim);
        orgBV.resize(dwOrgADim);
    }
    catch (std::bad_alloc&)
    {
        return E_OUTOFMEMORY;
    }

    // 2. Fill the linear equation
    for (size_t ii=0; ii<m_dwVertNumber; ii++)
    {
        if (m_pVerts[ii].bIsBoundary)
        {
            continue;
        }
    
        auto& adjacent = m_pVerts[ii].vertAdjacent;
        double bu = 0, bv = 0;

        orgA.setItem(vertMap[ii], vertMap[ii], double(adjacent.size()));
        for (size_t jj=0; jj<adjacent.size(); jj++)
        {
            uint32_t dwAdj = adjacent[jj];
            
            if (m_pVerts[dwAdj].bIsBoundary)
            {
                bu += boundTable[vertMap[dwAdj]*2];
                bv += boundTable[vertMap[dwAdj]*2+1];
            }
            else
            {
                orgA.setItem(vertMap[ii], vertMap[dwAdj], double(-1));	
            }
        }
        orgBU[vertMap[ii]] = bu;
        orgBV[vertMap[ii]] = bv;
    }

    // 3. get Symmetric matrix
    // A' = A^T * A
    if (!CSparseMatrix<double>::Mat_Trans_MUL_Mat(A, orgA))
    {
        return E_OUTOFMEMORY;
    }

    // B' = A^T * b
    if (!CSparseMatrix<double>::Mat_Trans_Mul_Vec(BU, orgA, orgBU))
    {
        return E_OUTOFMEMORY;
    }

    if (!CSparseMatrix<double>::Mat_Trans_Mul_Vec(BV, orgA, orgBV))
    {
        return E_OUTOFMEMORY;
    }
    
    return hr;
}