• ASSIMP概述


    阅读更多

    在3D渲染的时候,工作量比较大且比较麻烦的一件事就是建模,如果想降低这种麻烦就需要借用网络上已经存在的一些模型素材,至少这是非商用渲染程序常用手段(咱们自己写例子的时候经常这样做)。但是,由于网络中的模型格式众多,如果自己一一去解析代价也挺高的。ASSIMP作为一个开源项目,设计了一套可扩展的架构,为模型的导入导出提供了良好的支持。这里说的导入是把模型文件,解析成ASSIMP自身定义的一套模型,而导出即是把自身建立的模型结构导出为模型文件。

    ASSIMP默认提供了网络上比较流行的多种模型文件格式的导入和导出,如果我们仍需要对一下特殊的文件格式做这些操作,可以自己扩展。

    Importer :

    Cpp代码   收藏代码
    1. //1.注册模型导入实现类,BaseImporter对应的是一种具体的格式的模型文件  
    2. aiReturn RegisterLoader(BaseImporter* pImp);  
    3. aiReturn UnregisterLoader(BaseImporter* pImp);  
    4.   
    5. //2.注册处理过程,BaseProcess对应一个加载后的处理过程,例如把所有的非三角形网格变成三角形网格之类的,功能很强大  
    6. aiReturn RegisterPPStep(BaseProcess* pImp);  
    7. aiReturn UnregisterPPStep(BaseProcess* pImp);  
    8.   
    9. //3.各种属性  
    10. void SetPropertyInteger(const char* szName, int iValue, bool*   bWasExisting = NULL);  
    11. void SetPropertyBool(const char* szName, bool value, bool* bWasExisting = NULL) {  
    12.         SetPropertyInteger(szName,value,bWasExisting);  
    13.     }  
    14. void SetPropertyFloat(const char* szName, float fValue, bool* bWasExisting = NULL);  
    15. void SetPropertyString(const char* szName, const std::string& sValue, bool* bWasExisting = NULL);  
    16. int GetPropertyInteger(const char* szName, int iErrorReturn = 0xffffffff) const;  
    17. bool GetPropertyBool(const char* szName, bool bErrorReturn = falseconst {  
    18.         return GetPropertyInteger(szName,bErrorReturn)!=0;  
    19.     }  
    20. float GetPropertyFloat(const char* szName, float fErrorReturn = 10e10f) const;  
    21. const std::string& GetPropertyString(const char* szName,const std::string& sErrorReturn = ""const;  
    22.   
    23. //4.IOSystem只有一个,这是ASSIMP封住好的读写文件的类,这功能不需要扩展。  
    24. void SetIOHandler( IOSystem* pIOHandler);  
    25. IOSystem* GetIOHandler() const;  
    26. bool IsDefaultIOHandler() const;  
    27.   
    28. //5.这个是意淫中的功能至少我的用的3.0版本里面,它还不是一个功能。  
    29. void SetProgressHandler ( ProgressHandler* pHandler );  
    30. ProgressHandler* GetProgressHandler() const;  
    31. bool IsDefaultProgressHandler() const;  
    32. bool ValidateFlags(unsigned int pFlags) const;  
    33.   
    34. //6.读文件最终获得一个aiScene对象  
    35. const aiScene* ReadFile(const char* pFile, unsigned int pFlags);  
    36. const aiScene* ReadFileFromMemory( const void* pBuffer,size_t pLength,unsigned int pFlags,const char* pHint = "");  
    37. const aiScene* ApplyPostProcessing(unsigned int pFlags);  
    38. const aiScene* ReadFile(const std::string& pFile, unsigned int pFlags);  
    39. void FreeScene( );  
    40. const char* GetErrorString() const;  
    41. const aiScene* GetScene() const;  
    42. aiScene* GetOrphanedScene();  
    //1.注册模型导入实现类,BaseImporter对应的是一种具体的格式的模型文件
    aiReturn RegisterLoader(BaseImporter* pImp);
    aiReturn UnregisterLoader(BaseImporter* pImp);
    

    //2.注册处理过程,BaseProcess对应一个加载后的处理过程,例如把所有的非三角形网格变成三角形网格之类的,功能很强大
    aiReturn RegisterPPStep(BaseProcess* pImp);
    aiReturn UnregisterPPStep(BaseProcess* pImp);

    //3.各种属性
    void SetPropertyInteger(const char* szName, int iValue, bool* bWasExisting = NULL);
    void SetPropertyBool(const char* szName, bool value, bool* bWasExisting = NULL) {
    SetPropertyInteger(szName,value,bWasExisting);
    }
    void SetPropertyFloat(const char* szName, float fValue, bool* bWasExisting = NULL);
    void SetPropertyString(const char* szName, const std::string& sValue, bool* bWasExisting = NULL);
    int GetPropertyInteger(const char* szName, int iErrorReturn = 0xffffffff) const;
    bool GetPropertyBool(const char* szName, bool bErrorReturn = false) const {
    return GetPropertyInteger(szName,bErrorReturn)!=0;
    }
    float GetPropertyFloat(const char* szName, float fErrorReturn = 10e10f) const;
    const std::string& GetPropertyString(const char* szName,const std::string& sErrorReturn = “”) const;

    //4.IOSystem只有一个,这是ASSIMP封住好的读写文件的类,这功能不需要扩展。
    void SetIOHandler( IOSystem* pIOHandler);
    IOSystem* GetIOHandler() const;
    bool IsDefaultIOHandler() const;

    //5.这个是意淫中的功能至少我的用的3.0版本里面,它还不是一个功能。
    void SetProgressHandler ( ProgressHandler* pHandler );
    ProgressHandler* GetProgressHandler() const;
    bool IsDefaultProgressHandler() const;
    bool ValidateFlags(unsigned int pFlags) const;

    //6.读文件最终获得一个aiScene对象
    const aiScene* ReadFile(const char* pFile, unsigned int pFlags);
    const aiScene* ReadFileFromMemory( const void* pBuffer,size_t pLength,unsigned int pFlags,const char* pHint = “”);
    const aiScene* ApplyPostProcessing(unsigned int pFlags);
    const aiScene* ReadFile(const std::string& pFile, unsigned int pFlags);
    void FreeScene( );
    const char* GetErrorString() const;
    const aiScene* GetScene() const;
    aiScene* GetOrphanedScene();

    由于导入模型和导出模型是两个不相干的事情,所以在ASSIMP里面它们是没有任何联系的,Importer 作为导入模型的入口类,其管理的角色比较明显。以这种服务注册的模式,使代码的结构更松散。另外,上述对象都保存在ImporterPimpl里面而不是Importer 里面。

    读取模型的过程:

    Cpp代码   收藏代码
    1. //把完整的方法的主要内容提取出来  
    2. const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)  
    3. {  
    4.       // 1. 释放掉旧的内容  
    5.       if (pimpl->mScene){  
    6.              FreeScene();  
    7.        }  
    8.   
    9.       // 2.找出可以读当前文件的插件,这里存在一个隐患,如果列表里面有多个满足此文件,第一个优先采纳。  
    10.       BaseImporter* imp = NULL;  
    11.       for( unsigned int a = 0; a < pimpl->mImporter.size(); a++){  
    12.             if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, false)) {  
    13.         imp = pimpl->mImporter[a];  
    14.         break;  
    15.         }  
    16.        }  
    17.       //... 这里略过一堆蛋疼的代码,不知道编程的人怎么想的,我觉得上面就够了。  
    18.   
    19.       // 3.先更新Progress,然后再解析模型  
    20.       pimpl->mProgressHandler->Update();  
    21.       pimpl->mScene = imp->ReadFile( this, pFile, pimpl->mIOHandler);  
    22.       pimpl->mProgressHandler->Update();  // 这里为啥又要调一次?不懂  
    23.   
    24.       // 4. 这个地方还有一个后处理步骤  
    25.       if( pimpl->mScene){  
    26.         ScenePreprocessor pre(pimpl->mScene);  
    27.         pre.ProcessScene();  
    28.         pimpl->mProgressHandler->Update();  
    29.         ApplyPostProcessing(pFlags & (~aiProcess_ValidateDataStructure));  
    30.     }  
    31.     pimpl->mPPShared->Clean();  
    32.     return pimpl->mScene;  
    33. }  
    //把完整的方法的主要内容提取出来
    const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
    {
          // 1. 释放掉旧的内容
          if (pimpl->mScene){
                 FreeScene();
           }
    
      // 2.找出可以读当前文件的插件,这里存在一个隐患,如果列表里面有多个满足此文件,第一个优先采纳。
      BaseImporter* imp = NULL;
      for( unsigned int a = 0; a &lt; pimpl-&gt;mImporter.size(); a++){
            if( pimpl-&gt;mImporter[a]-&gt;CanRead( pFile, pimpl-&gt;mIOHandler, false)) {
    	imp = pimpl-&gt;mImporter[a];
    	break;
        }
       }
      //... 这里略过一堆蛋疼的代码,不知道编程的人怎么想的,我觉得上面就够了。
    
      // 3.先更新Progress,然后再解析模型
      pimpl-&gt;mProgressHandler-&gt;Update();
      pimpl-&gt;mScene = imp-&gt;ReadFile( this, pFile, pimpl-&gt;mIOHandler);
      pimpl-&gt;mProgressHandler-&gt;Update();  // 这里为啥又要调一次?不懂
    
      // 4. 这个地方还有一个后处理步骤
      if( pimpl-&gt;mScene){
    	ScenePreprocessor pre(pimpl-&gt;mScene);
    	pre.ProcessScene();
    	pimpl-&gt;mProgressHandler-&gt;Update();
    	ApplyPostProcessing(pFlags &amp; (~aiProcess_ValidateDataStructure));
    }
    pimpl-&gt;mPPShared-&gt;Clean();
    return pimpl-&gt;mScene;
    

    }

    浓缩版的ReadFile方法,描述了整个解析过程,细节不再关注,这个插件主要强调的是用而不是修改。

    支持的数据格式:

    Assimp(Open Asset Import Library)是一个支持读取多种模型资源的开源库,当前最新的版本是3.0版,支持读取以下类型的3D模型:

    • Collada ( .dae )
    • Blender 3D ( .blend )
    • 3ds Max 3DS ( .3ds )
    • 3ds Max ASE ( .ase )
    • Wavefront Object ( .obj )
    • Industry Foundation Classes (IFC/Step) ( .ifc )
    • XGL ( .xgl,.zgl )
    • Stanford Polygon Library ( .ply )
    • *AutoCAD DXF ( .dxf )
    • LightWave ( .lwo )
    • LightWave Scene ( .lws )
    • Modo ( .lxo )
    • Stereolithography ( .stl )
    • DirectX X ( .x )
    • AC3D ( .ac )
    • Milkshape 3D ( .ms3d )
    • * TrueSpace ( .cob,.scn )Biovision BVH ( .bvh )
    • * CharacterStudio Motion ( .csm )Ogre XML ( .xml )
    • Irrlicht Mesh ( .irrmesh )
    • * Irrlicht Scene ( .irr )
    • Quake I ( .mdl )
    • Quake II ( .md2 )
    • Quake III Mesh ( .md3 )
    • Quake III Map/BSP ( .pk3 )
    • * Return to Castle Wolfenstein ( .mdc )
    • Doom 3 ( .md5* )
    • *Valve Model ( .smd,.vta )
    • *Starcraft II M3 ( .m3 )
    • *Unreal ( .3d )BlitzBasic 3D ( .b3d )
    • Quick3D ( .q3d,.q3s )
    • Neutral File Format ( .nff )
    • Sense8 WorldToolKit ( .nff )
    • Object File Format ( .off )
    • PovRAY Raw ( .raw )
    • Terragen Terrain ( .ter )
    • 3D GameStudio (3DGS) ( .mdl )
    • 3D GameStudio (3DGS) Terrain ( .hmp )
    • Izware Nendo ( .ndo )

    支持以下格式的导出:

    • Collada ( .dae )
    • Wavefront Object ( .obj )
    • Stereolithography ( .stl )
    • Stanford Polygon Library ( .ply )

    此外还支持对导入的模型做一些常用的处理,如把四边形转换为三角形、计算切线和副法线、将大模型分割为小模型等。

      <a href="/blog/1756120" class="next" title="ASSIMP的数据结构">ASSIMP的数据结构</a>   
    
  • 相关阅读:
    gnats配置文件
    在Mac中安装python,配置python环境
    利用git bash和git gui向git远程仓库提交文件
    os模块
    django中的locale()函数
    django配置静态文件
    sso单点登录
    django get_object_or_404
    关于token
    Django的CSRF机制
  • 原文地址:https://www.cnblogs.com/szmtjs10/p/16110346.html
Copyright © 2020-2023  润新知