Assimp import postprocessing

Assimp模型库导入后处理参数介绍

Posted by Tao on Friday, December 10, 2021

本文对应postprocess.h头文件

导入示例

#include <assimp/Importer.hpp>      // C++ importer interface
#include <assimp/scene.h>           // Output data structure
#include <assimp/postprocess.h>     // Post processing flags

bool DoTheImportThing( const std::string& pFile) {
  // Create an instance of the Importer class
  Assimp::Importer importer;

  // And have it read the given file with some example postprocessing
  // Usually - if speed is not the most important aspect for you - you'll
  // probably to request more postprocessing than we do in this example.
  const aiScene* scene = importer.ReadFile( pFile,
    aiProcess_CalcTangentSpace       |
    aiProcess_Triangulate            |
    aiProcess_JoinIdenticalVertices  |
    aiProcess_SortByPType);

  // If the import failed, report it
  if (nullptr != scene) {
    DoTheErrorLogging( importer.GetErrorString());
    return false;
  }

  // Now we can access the file's contents.
  DoTheSceneProcessing( scene);

  // We're done. Everything will be cleaned up by the importer destructor
  return true;
}

参数介绍

ASSIMP_API const C_STRUCT aiScene* aiImportFile(
    const char* pFile,
    unsigned int pFlags);
enum aiPostProcessSteps
{
    /** <hr>Calculates the tangents and bitangents for the imported meshes.
     *
     * Does nothing if a mesh does not have normals. You might want this post
     * processing step to be executed if you plan to use tangent space calculations
     * such as normal mapping  applied to the meshes. There's an importer property,
     * <tt>#AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE</tt>, which allows you to specify
     * a maximum smoothing angle for the algorithm. However, usually you'll
     * want to leave it at the default value.
     * 重新计算网格切线,切线主要用于bump-mapped shaders
     */
    aiProcess_CalcTangentSpace = 0x1,
    /** <hr>Identifies and joins identical vertex data sets within all
     *  imported meshes.
     *
     * After this step is run, each mesh contains unique vertices,
     * so a vertex may be used by multiple faces. You usually want
     * to use this post processing step. If your application deals with
     * indexed geometry, this step is compulsory or you'll just waste rendering
     * time. <b>If this flag is not specified</b>, no vertices are referenced by
     * more than one face and <b>no index buffer is required</b> for rendering.
     * 合并相同顶点
     */
    aiProcess_JoinIdenticalVertices = 0x2,
    aiProcess_MakeLeftHanded = 0x4,
    /** <hr>Triangulates all faces of all meshes.
     *
     * 所有的面全部转为三角面
     * By default the imported mesh data might contain faces with more than 3
     * indices. For rendering you'll usually want all faces to be triangles.
     * This post processing step splits up faces with more than 3 indices into
     * triangles. Line and point primitives are *not* modified! If you want
     * 'triangles only' with no other kinds of primitives, try the following
     * solution:
     * <ul>
     * <li>Specify both #aiProcess_Triangulate and #aiProcess_SortByPType </li>
     * <li>Ignore all point and line meshes when you process assimp's output</li>
     * </ul>
     */
    aiProcess_Triangulate = 0x8,
    /** <hr>Removes some parts of the data structure (animations, materials,
     *  light sources, cameras, textures, vertex components).
     * 去除部分数据
     *
     * The  components to be removed are specified in a separate
     * importer property, <tt>#AI_CONFIG_PP_RVC_FLAGS</tt>. This is quite useful
     * if you don't need all parts of the output structure. Vertex colors
     * are rarely used today for example... Calling this step to remove unneeded
     * data from the pipeline as early as possible results in increased
     * performance and a more optimized output data structure.
     * This step is also useful if you want to force Assimp to recompute
     * normals or tangents.(强制计算法线与切线) The corresponding steps don't recompute them if
     * they're already there (loaded from the source asset). By using this
     * step you can make sure they are NOT there.
     *
     * This flag is a poor one, mainly because its purpose is usually
     * misunderstood. Consider the following case: a 3D model has been exported
     * from a CAD app, and it has per-face vertex colors. Vertex positions can't be
     * shared, thus the #aiProcess_JoinIdenticalVertices step fails to
     * optimize the data because of these nasty little vertex colors.
     * Most apps don't even process them, so it's all for nothing. By using
     * this step, unneeded components are excluded as early as possible
     * thus opening more room for internal optimizations.
     */
    aiProcess_RemoveComponent = 0x10,
     /** <hr>Generates normals for all faces of all meshes.
     *
     * This is ignored if normals are already there at the time this flag
     * is evaluated. Model importers try to load them from the source file, so
     * they're usually already there. Face normals are shared between all points
     * of a single face, so a single point can have multiple normals, which
     * forces the library to duplicate vertices in some cases.
     * #aiProcess_JoinIdenticalVertices is *senseless* then.
     *
     * This flag may not be specified together with #aiProcess_GenSmoothNormals.
     * 不能与aiProcess_GenSmoothNormals同时设置
     */
    aiProcess_GenNormals = 0x20,
    aiProcess_GenSmoothNormals = 0x40,
    /** <hr>Splits large meshes into smaller sub-meshes.
    *
    * This is quite useful for real-time rendering, where the number of triangles
    * which can be maximally processed in a single draw-call is limited
    * by the video driver/hardware. The maximum vertex buffer is usually limited
    * too. Both requirements can be met with this step: you may specify both a
    * triangle and vertex limit for a single mesh.
    *
    * The split limits can (and should!) be set through the
    * <tt>#AI_CONFIG_PP_SLM_VERTEX_LIMIT</tt> and <tt>#AI_CONFIG_PP_SLM_TRIANGLE_LIMIT</tt>
    * importer properties. The default values are <tt>#AI_SLM_DEFAULT_MAX_VERTICES</tt> and
    * <tt>#AI_SLM_DEFAULT_MAX_TRIANGLES</tt>.
    *
    * Note that splitting is generally a time-consuming task, but only if there's
    * something to split. The use of this step is recommended for most users.
    */
    aiProcess_SplitLargeMeshes = 0x80,
    /** <hr>Removes the node graph and pre-transforms all vertices with
    * the local transformation matrices of their nodes.
    * 去除除根节点外的所有node,会去除动画
    *
    * The output scene still contains nodes, however there is only a
    * root node with children, each one referencing only one mesh,
    * and each mesh referencing one material.(只有一个带有子节点的根节点,每个节点node只引用一个网格mesh,每个网格对应一种材质。) For rendering, you can
    * simply render all meshes in order - you don't need to pay
    * attention to local transformations and the node hierarchy.
    * Animations are removed during this step.
    * This step is intended for applications without a scenegraph.
    * The step CAN cause some problems: if e.g. a mesh of the asset
    * contains normals and another, using the same material index, does not,
    * they will be brought together, but the first meshes's part of
    * the normal list is zeroed. However, these artifacts are rare.
    * @note The <tt>#AI_CONFIG_PP_PTV_NORMALIZE</tt> configuration property
    * can be set to normalize the scene's spatial dimension to the -1...1
    * range.
    */
    aiProcess_PreTransformVertices = 0x100,
    /** <hr>Limits the number of bones simultaneously affecting a single vertex
    *  to a maximum value.
    * 骨骼动画相关
    *
    * If any vertex is affected by more than the maximum number of bones, the least
    * important vertex weights are removed and the remaining vertex weights are
    * renormalized so that the weights still sum up to 1.
    * The default bone weight limit is 4 (defined as <tt>#AI_LMW_MAX_WEIGHTS</tt> in
    * config.h), but you can use the <tt>#AI_CONFIG_PP_LBW_MAX_WEIGHTS</tt> importer
    * property to supply your own limit to the post processing step.
    *
    * If you intend to perform the skinning in hardware, this post processing
    * step might be of interest to you.
    */
    aiProcess_LimitBoneWeights = 0x200,
    /** <hr>Validates the imported scene data structure.
    * This makes sure that all indices are valid, all animations and
    * bones are linked correctly, all material references are correct .. etc.
    * 验证导入的场景数据结构。这可以确保所有索引都有效,所有动画和骨骼都正确链接,所有材质参考都正确
    *
    * It is recommended that you capture Assimp's log output if you use this flag,
    * so you can easily find out what's wrong if a file fails the
    * validation. The validator is quite strict and will find *all*
    * inconsistencies in the data structure... It is recommended that plugin
    * developers use it to debug their loaders. There are two types of
    * validation failures:
    * <ul>
    * <li>Error: There's something wrong with the imported data. Further
    *   postprocessing is not possible and the data is not usable at all.
    *   The import fails. #Importer::GetErrorString() or #aiGetErrorString()
    *   carry the error message around.</li>
    * <li>Warning: There are some minor issues (e.g. 1000000 animation
    *   keyframes with the same time), but further postprocessing and use
    *   of the data structure is still safe. Warning details are written
    *   to the log file, <tt>#AI_SCENE_FLAGS_VALIDATION_WARNING</tt> is set
    *   in #aiScene::mFlags</li>
    * </ul>
    *
    * This post-processing step is not time-consuming. Its use is not
    * compulsory, but recommended.
    */
    aiProcess_ValidateDataStructure = 0x400,
    /** <hr>Reorders triangles for better vertex cache locality.
    * 缓存相关
    *
    * The step tries to improve the ACMR (average post-transform vertex cache
    * miss ratio) for all meshes. The implementation runs in O(n) and is
    * roughly based on the 'tipsify' algorithm (see <a href="
    * http://www.cs.princeton.edu/gfx/pubs/Sander_2007_%3ETR/tipsy.pdf">this
    * paper</a>).
    *
    * If you intend to render huge models in hardware, this step might
    * be of interest to you. The <tt>#AI_CONFIG_PP_ICL_PTCACHE_SIZE</tt>
    * importer property can be used to fine-tune the cache optimization.
    */
    aiProcess_ImproveCacheLocality = 0x800,
    /** <hr>Searches for redundant/unreferenced materials and removes them.
    * 移除冗余或未引用材质,与#aiProcess_PretransformVertices及#aiProcess_OptimizeMeshes合用最优
    *
    * This is especially useful in combination with the
    * #aiProcess_PreTransformVertices and #aiProcess_OptimizeMeshes flags.
    * Both join small meshes with equal characteristics, but they can't do
    * their work if two meshes have different materials. Because several
    * material settings are lost during Assimp's import filters,
    * (and because many exporters don't check for redundant materials), huge
    * models often have materials which are are defined several times with
    * exactly the same settings.
    *
    * Several material settings not contributing to the final appearance of
    * a surface are ignored in all comparisons (e.g. the material name).
    * So, if you're passing additional information through the
    * content pipeline (probably using *magic* material names), don't
    * specify this flag. Alternatively take a look at the
    * <tt>#AI_CONFIG_PP_RRM_EXCLUDE_LIST</tt> importer property.
    */
    aiProcess_RemoveRedundantMaterials = 0x1000,
    /** <hr>This step tries to determine which meshes have normal vectors
    * that are facing inwards and inverts them.
    * 翻转向内的法线(建议开启)
    *
    * The algorithm is simple but effective:
    * the bounding box of all vertices + their normals is compared against
    * the volume of the bounding box of all vertices without their normals.
    * This works well for most objects, problems might occur with planar
    * surfaces. However, the step tries to filter such cases.
    * The step inverts all in-facing normals. Generally it is recommended
    * to enable this step, although the result is not always correct.
    */
    aiProcess_FixInfacingNormals = 0x2000,
    /** <hr>This step splits meshes with more than one primitive type in
    *  homogeneous sub-meshes.
    * 此步骤将具有多个基本类型的网格拆分为同质子网格。PrimitiveType排序便于去除点线
    *
    *  The step is executed after the triangulation step. After the step
    *  returns, just one bit is set in aiMesh::mPrimitiveTypes. This is
    *  especially useful for real-time rendering where point and line
    *  primitives are often ignored or rendered separately.
    *  You can use the <tt>#AI_CONFIG_PP_SBP_REMOVE</tt> importer property to
    *  specify which primitive types you need. This can be used to easily
    *  exclude lines and points, which are rarely used, from the import.
    */
    aiProcess_SortByPType = 0x8000,
    /** <hr>This step searches all meshes for degenerate primitives and
    *  converts them to proper lines or points.
    * 删除点线等其他图元
    *
    * A face is 'degenerate' if one or more of its points are identical.
    * To have the degenerate stuff not only detected and collapsed but
    * removed, try one of the following procedures:
    * <br><b>1.</b> (if you support lines and points for rendering but don't
    *    want the degenerates)<br>
    * <ul>
    *   <li>Specify the #aiProcess_FindDegenerates flag.
    *   </li>
    *   <li>Set the <tt>#AI_CONFIG_PP_FD_REMOVE</tt> importer property to
    *       1. This will cause the step to remove degenerate triangles from the
    *       import as soon as they're detected. They won't pass any further
    *       pipeline steps.
    *   </li>
    * </ul>
    * <br><b>2.</b>(if you don't support lines and points at all)<br>
    * <ul>
    *   <li>Specify the #aiProcess_FindDegenerates flag.
    *   </li>
    *   <li>Specify the #aiProcess_SortByPType flag. This moves line and
    *     point primitives to separate meshes.
    *   </li>
    *   <li>Set the <tt>#AI_CONFIG_PP_SBP_REMOVE</tt> importer property to
    *       @code aiPrimitiveType_POINTS | aiPrimitiveType_LINES
    *       @endcode to cause SortByPType to reject point
    *       and line meshes from the scene.
    *   </li>
    * </ul>
    *
    * This step also removes very small triangles with a surface area smaller
    * than 10^-6. If you rely on having these small triangles, or notice holes
    * in your model, set the property <tt>#AI_CONFIG_PP_FD_CHECKAREA</tt> to
    * false.
    * @note Degenerate polygons are not necessarily evil and that's why
    * they're not removed by default. There are several file formats which
    * don't support lines or points, and some exporters bypass the
    * format specification and write them as degenerate triangles instead.
    */
    aiProcess_FindDegenerates = 0x10000,
    /** <hr>This step searches all meshes for invalid data, such as zeroed
    *  normal vectors or invalid UV coords and removes/fixes them. This is
    *  intended to get rid of some common exporter errors.
    * 移除错误数据
    *
    * This is especially useful for normals. If they are invalid, and
    * the step recognizes this, they will be removed and can later
    * be recomputed, i.e. by the #aiProcess_GenSmoothNormals flag.<br>
    * The step will also remove meshes that are infinitely small and reduce
    * animation tracks consisting of hundreds if redundant keys to a single
    * key. The <tt>AI_CONFIG_PP_FID_ANIM_ACCURACY</tt> config property decides
    * the accuracy of the check for duplicate animation tracks.
    */
    aiProcess_FindInvalidData = 0x20000,
    aiProcess_GenUVCoords = 0x40000,
    /** <hr>This step applies per-texture UV transformations and bakes
    *  them into stand-alone vtexture coordinate channels.
    *
    * UV transformations are specified per-texture - see the
    * <tt>#AI_MATKEY_UVTRANSFORM</tt> material key for more information.
    * This step processes all textures with
    * transformed input UV coordinates and generates a new (pre-transformed) UV channel
    * which replaces the old channel. Most applications won't support UV
    * transformations, so you will probably want to specify this step.
    *
    * @note UV transformations are usually implemented in real-time apps by
    * transforming texture coordinates at vertex shader stage with a 3x3
    * (homogenous) transformation matrix.
    */
    aiProcess_TransformUVCoords = 0x80000,
    /** <hr>This step searches for duplicate meshes and replaces them
    *  with references to the first mesh.
    *
    *  This step takes a while, so don't use it if speed is a concern.
    *  Its main purpose is to workaround the fact that many export
    *  file formats don't support instanced meshes, so exporters need to
    *  duplicate meshes. This step removes the duplicates again. Please
    *  note that Assimp does not currently support per-node material
    *  assignment to meshes, which means that identical meshes with
    *  different materials are currently *not* joined, although this is
    *  planned for future versions.
    */
    aiProcess_FindInstances = 0x100000,
    /** <hr>A post-processing step to reduce the number of meshes.
    * 降低drawcall
    *
    *  This will, in fact, reduce the number of draw calls.
    *
    *  This is a very effective optimization and is recommended to be used
    *  together with #aiProcess_OptimizeGraph, if possible. The flag is fully
    *  compatible with both #aiProcess_SplitLargeMeshes and #aiProcess_SortByPType.
    */
    aiProcess_OptimizeMeshes  = 0x200000,
    /** <hr>A post-processing step to optimize the scene hierarchy.
    *
    *  Nodes without animations, bones, lights or cameras assigned are
    *  collapsed and joined.
    *
    *  Node names can be lost during this step. If you use special 'tag nodes'
    *  to pass additional information through your content pipeline, use the
    *  <tt>#AI_CONFIG_PP_OG_EXCLUDE_LIST</tt> importer property to specify a
    *  list of node names you want to be kept. Nodes matching one of the names
    *  in this list won't be touched or modified.
    *
    *  Use this flag with caution. Most simple files will be collapsed to a
    *  single node, so complex hierarchies are usually completely lost.(大多数简单的文件将被折叠单个节点,因此复杂的层次结构通常会完全丢失。) This is not
    *  useful for editor environments, but probably a very effective
    *  optimization if you just want to get the model data, convert it to your
    *  own format, and render it as fast as possible.
    *
    *  This flag is designed to be used with #aiProcess_OptimizeMeshes for best
    *  results.
    *
    *  @note 'Crappy' scenes with thousands of extremely small meshes packed
    *  in deeply nested nodes exist for almost all file formats.
    *  #aiProcess_OptimizeMeshes in combination with #aiProcess_OptimizeGraph
    *  usually fixes them all and makes them renderable.
    */
    aiProcess_OptimizeGraph  = 0x400000,
}

「如果这篇文章对你有用,请随意打赏」

Heisenberg Blog

如果这篇文章对你有用,请随意打赏

使用微信扫描二维码完成支付


comments powered by Disqus