Assimp加载较大的OBJ模型

  最近用Assimp加载较大OBJ模型时发现内存会爆满,看了下源码,问题在于解析OBJ文件时是一次解析全部 开辟的内存没有及时的释放 。

这是解析的源码

void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
    // only update every 100KB or it'll be too slow
    //const unsigned int updateProgressEveryBytes = 100 * 1024;
    unsigned int progressCounter = 0;
    const unsigned int bytesToProcess = static_cast<unsigned int>(streamBuffer.size());
    const unsigned int progressTotal = bytesToProcess;
    unsigned int processed = 0;
    size_t lastFilePos( 0 );

    std::vector<char> buffer;
    while ( streamBuffer.getNextDataLine( buffer, '\0' ) ) {
        m_DataIt = buffer.begin();
        m_DataItEnd = buffer.end();

        // Handle progress reporting
        const size_t filePos( streamBuffer.getFilePos() );
        if ( lastFilePos < filePos ) {
            processed = static_cast<unsigned int>(filePos);
            lastFilePos = filePos;
            progressCounter++;
            m_progress->UpdateFileRead( processed, progressTotal );
        }

        // parse line
        switch (*m_DataIt) {
        case 'v': // Parse a vertex texture coordinate
            {
			
                ++m_DataIt;
                if (*m_DataIt == ' ' || *m_DataIt == '\t') {
                    size_t numComponents = getNumComponentsInDataDefinition();
                    if (numComponents == 3) {
                        // read in vertex definition
						m_isVN = false;
                        getVector3(m_pModel->m_Vertices);
                    } else if (numComponents == 4) {
                        // read in vertex definition (homogeneous coords)
                        getHomogeneousVector3(m_pModel->m_Vertices);
                    } else if (numComponents == 6) {
                        // read vertex and vertex-color
                        getTwoVectors3(m_pModel->m_Vertices, m_pModel->m_VertexColors);
                    }
                } else if (*m_DataIt == 't') {
                    // read in texture coordinate ( 2D or 3D )
                    ++m_DataIt;
                    getVector( m_pModel->m_TextureCoord );
                } else if (*m_DataIt == 'n') {
                    // Read in normal vector definition
                    ++m_DataIt;
					m_isVN = true;
                    getVector3( m_pModel->m_Normals );
                }
            }
            break;

        case 'p': // Parse a face, line or point statement
        case 'l':
        case 'f':
            {
                getFace(*m_DataIt == 'f' ? aiPrimitiveType_POLYGON : (*m_DataIt == 'l'
                    ? aiPrimitiveType_LINE : aiPrimitiveType_POINT));
            }
            break;

        case '#': // Parse a comment
            {
                getComment();
            }
            break;

        case 'u': // Parse a material desc. setter
            {
                std::string name;

                getNameNoSpace(m_DataIt, m_DataItEnd, name);

                size_t nextSpace = name.find(" ");
                if (nextSpace != std::string::npos)
                    name = name.substr(0, nextSpace);

                if(name == "usemtl")
                {
                    getMaterialDesc();
                }
            }
            break;

        case 'm': // Parse a material library or merging group ('mg')
            {
                std::string name;

                getNameNoSpace(m_DataIt, m_DataItEnd, name);

                size_t nextSpace = name.find(" ");
                if (nextSpace != std::string::npos)
                    name = name.substr(0, nextSpace);

                if (name == "mg")
                    getGroupNumberAndResolution();
                else if(name == "mtllib")
                    getMaterialLib();
				else
					goto pf_skip_line;
            }
            break;

        case 'g': // Parse group name
            {
                getGroupName();
            }
            break;

        case 's': // Parse group number
            {
                getGroupNumber();
            }
            break;

        case 'o': // Parse object name
            {
                getObjectName();
            }
            break;

        default:
            {
pf_skip_line:
                m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
            }
            break;
        }
    }
	m_filePath.push_back(m_curPath);
}

会在解析f的时候new出Face类型 直到文件读完 由于OJB文件较大所以会内存爆满

 ObjFile::Face *face = new ObjFile::Face( type );

暂时优化的方案 按块现将face的数据写入文件里面保存 face直接释放  

挡块多的时候要管理好路径,后面的赋值也方便

读出来直接从这个CreateDataFromImport(parser.GetModel(), pScene, pParser);函数里面赋值

这个函数也是按照块来赋值 ,在下面循环里读取并赋值给pModel->m_Meshes[index]->m_Faces。 也可以直接赋值个pScene 这样做比较麻烦要改大量代码

  for (size_t index = 0; index < pModel->m_Objects.size(); ++index) 

经过这个函数createNodes(pModel, pModel->m_Objects[index], pScene->mRootNode, pScene, MeshArray);之后要把之前赋值的pModel->m_Meshes[index]->m_Faces全部释放掉。

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值