_ZN6Assimp19Discreet3DSImporterC2Ev:
  104|  3.48k|        mStream(nullptr), mLastNodeIndex(), mCurrentNode(), mRootNode(), mScene(), mMasterScale(), bHasBG(), bIsPrj() {
  105|       |    // empty
  106|  3.48k|}
_ZNK6Assimp19Discreet3DSImporter7GetInfoEv:
  117|  3.48k|const aiImporterDesc *Discreet3DSImporter::GetInfo() const {
  118|  3.48k|    return &desc;
  119|  3.48k|}

_ZN6Assimp19Discreet3DSImporterD2Ev:
   65|  3.48k|    ~Discreet3DSImporter() override = default;

_ZNK6Assimp12D3MFImporter7GetInfoEv:
  101|  3.48k|const aiImporterDesc *D3MFImporter::GetInfo() const {
  102|  3.48k|    return &desc;
  103|  3.48k|}

_ZN6Assimp12D3MFImporterC2Ev:
   59|  3.48k|    D3MFImporter() = default;

_ZN6Assimp12AC3DImporterC2Ev:
  161|  3.48k|        mBuffer(),
  162|       |        configSplitBFCull(),
  163|       |        configEvalSubdivision(),
  164|       |        mNumMeshes(),
  165|       |        mLights(),
  166|  3.48k|        mLightsCounter(0),
  167|  3.48k|        mGroupsCounter(0),
  168|  3.48k|        mPolysCounter(0),
  169|  3.48k|        mWorldsCounter(0) {
  170|       |    // nothing to be done here
  171|  3.48k|}
_ZNK6Assimp12AC3DImporter7GetInfoEv:
  182|  3.48k|const aiImporterDesc *AC3DImporter::GetInfo() const {
  183|  3.48k|    return &desc;
  184|  3.48k|}

_ZN6Assimp11AMFImporter5ClearEv:
   69|  3.48k|void AMFImporter::Clear() {
   70|  3.48k|    mNodeElement_Cur = nullptr;
   71|  3.48k|    mUnit.clear();
   72|  3.48k|    mMaterial_Converted.clear();
   73|  3.48k|    mTexture_Converted.clear();
   74|       |    // Delete all elements
   75|  3.48k|    if (!mNodeElement_List.empty()) {
  ------------------
  |  Branch (75:9): [True: 0, False: 3.48k]
  ------------------
   76|      0|        for (AMFNodeElementBase *ne : mNodeElement_List) {
  ------------------
  |  Branch (76:37): [True: 0, False: 0]
  ------------------
   77|      0|            delete ne;
   78|      0|        }
   79|       |
   80|      0|        mNodeElement_List.clear();
   81|      0|    }
   82|  3.48k|}
_ZN6Assimp11AMFImporterC2Ev:
   85|  3.48k|        mNodeElement_Cur(nullptr),
   86|  3.48k|        mXmlParser(nullptr) {
   87|       |    // empty
   88|  3.48k|}
_ZN6Assimp11AMFImporterD2Ev:
   90|  3.48k|AMFImporter::~AMFImporter() {
   91|  3.48k|    delete mXmlParser;
   92|       |    // Clear() is accounting if data already is deleted. So, just check again if all data is deleted.
   93|  3.48k|    Clear();
   94|  3.48k|}
_ZNK6Assimp11AMFImporter7GetInfoEv:
  487|  3.48k|const aiImporterDesc *AMFImporter::GetInfo() const {
  488|  3.48k|    return &Description;
  489|  3.48k|}

_ZN6Assimp11ASEImporterC2Ev:
   85|  3.48k|        mParser(), mBuffer(), pcScene(), configRecomputeNormals(), noSkeletonMesh() {
   86|       |    // empty
   87|  3.48k|}
_ZNK6Assimp11ASEImporter7GetInfoEv:
   98|  3.48k|const aiImporterDesc *ASEImporter::GetInfo() const {
   99|  3.48k|    return &desc;
  100|  3.48k|}

_ZNK6Assimp14AssbinImporter7GetInfoEv:
   82|  3.48k|const aiImporterDesc *AssbinImporter::GetInfo() const {
   83|  3.48k|    return &desc;
   84|  3.48k|}

_ZN6Assimp11B3DImporterD2Ev:
   91|  3.48k|B3DImporter::~B3DImporter() = default;
_ZNK6Assimp11B3DImporter7GetInfoEv:
  110|  3.48k|const aiImporterDesc *B3DImporter::GetInfo() const {
  111|  3.48k|    return &desc;
  112|  3.48k|}

_ZN6Assimp11B3DImporterC2Ev:
   66|  3.48k|    B3DImporter() = default;

_ZN6Assimp9BVHLoaderC2Ev:
   86|  3.48k|        noSkeletonMesh() {
   87|       |    // empty
   88|  3.48k|}
_ZNK6Assimp9BVHLoader7GetInfoEv:
  104|  3.48k|const aiImporterDesc *BVHLoader::GetInfo() const {
  105|  3.48k|    return &desc;
  106|  3.48k|}

_ZN6Assimp9BVHLoaderD2Ev:
   88|  3.48k|    ~BVHLoader() override = default;

_ZN6Assimp7Blender25CustomDataTypeDescriptionC2EPFbPNS0_8ElemBaseEmRKNS0_12FileDatabaseEEPFS3_mEPFvS3_E:
   77|     84|            Read(read), Create(create), Destroy(destroy) {}

_ZN6Assimp7Blender9TempArrayINSt3__16vectorENS0_15BlenderModifierEEC2Ev:
   67|  3.48k|        TempArray() = default;
_ZN6Assimp7Blender9TempArrayINSt3__16vectorENS0_15BlenderModifierEED2Ev:
   69|  3.48k|        ~TempArray () {
   70|  3.48k|            for(T* elem : arr) {
  ------------------
  |  Branch (70:25): [True: 0, False: 3.48k]
  ------------------
   71|      0|                delete elem;
   72|      0|            }
   73|  3.48k|        }

_ZN6Assimp15BlenderImporterC2Ev:
  101|  3.48k|        modifier_cache(new BlenderModifierShowcase()) {
  102|       |    // empty
  103|  3.48k|}
_ZN6Assimp15BlenderImporterD2Ev:
  107|  3.48k|BlenderImporter::~BlenderImporter() {
  108|  3.48k|    delete modifier_cache;
  109|  3.48k|}
_ZNK6Assimp15BlenderImporter7GetInfoEv:
  121|  3.48k|const aiImporterDesc *BlenderImporter::GetInfo() const {
  122|  3.48k|    return &blenderDesc;
  123|  3.48k|}

_ZNK6Assimp11COBImporter7GetInfoEv:
  102|  3.48k|const aiImporterDesc *COBImporter::GetInfo() const {
  103|  3.48k|    return &desc;
  104|  3.48k|}

_ZN6Assimp11COBImporterC2Ev:
   77|  3.48k|    COBImporter() = default;

_ZN6Assimp11CSMImporterC2Ev:
   76|  3.48k|CSMImporter::CSMImporter() : noSkeletonMesh() {
   77|       |    // empty
   78|  3.48k|}
_ZNK6Assimp11CSMImporter7GetInfoEv:
   89|  3.48k|const aiImporterDesc* CSMImporter::GetInfo () const {
   90|  3.48k|    return &desc;
   91|  3.48k|}

_ZN6Assimp13ColladaLoaderC2Ev:
  103|  3.48k|        noSkeletonMesh(false),
  104|  3.48k|        removeEmptyBones(false),
  105|  3.48k|        ignoreUpDirection(false),
  106|  3.48k|        ignoreUnitSize(false),
  107|  3.48k|        useColladaName(false),
  108|  3.48k|        mNodeNameCounter(0) {
  109|       |    // empty
  110|  3.48k|}
_ZNK6Assimp13ColladaLoader7GetInfoEv:
  136|  3.48k|const aiImporterDesc *ColladaLoader::GetInfo() const {
  137|  3.48k|    return &desc;
  138|  3.48k|}

_ZN6Assimp13ColladaLoaderD2Ev:
   91|  3.48k|    ~ColladaLoader() override = default;

_ZNK6Assimp11DXFImporter7GetInfoEv:
  363|  3.48k|const aiImporterDesc* DXFImporter::GetInfo () const {
  364|  3.48k|    return &desc;
  365|  3.48k|}

_ZN6Assimp11DXFImporterC2Ev:
   71|  3.48k|    DXFImporter() = default;

_ZN6Assimp3FBX14ImportSettingsC2Ev:
   54|  3.48k|            strictMode(true),
   55|  3.48k|            readAllLayers(true),
   56|  3.48k|            readAllMaterials(false),
   57|  3.48k|            readMaterials(true),
   58|  3.48k|            readTextures(true),
   59|  3.48k|            readCameras(true),
   60|  3.48k|            readLights(true),
   61|  3.48k|            readAnimations(true),
   62|  3.48k|            readWeights(true),
   63|  3.48k|            useSkeleton(false),
   64|  3.48k|            preservePivots(true),
   65|  3.48k|            optimizeEmptyAnimationCurves(true),
   66|  3.48k|            useLegacyEmbeddedTextureNaming(false),
   67|  3.48k|            removeEmptyBones(true),
   68|  3.48k|            convertToMeters(false) {
   69|       |        // empty
   70|  3.48k|    }

_ZNK6Assimp11FBXImporter7GetInfoEv:
   99|  3.48k|const aiImporterDesc *FBXImporter::GetInfo() const {
  100|  3.48k|	return &desc;
  101|  3.48k|}

_ZN6Assimp11FBXImporterC2Ev:
   73|  3.48k|    FBXImporter() = default;

_ZN6Assimp11HMPImporterC2Ev:
   75|  3.48k|HMPImporter::HMPImporter() = default;
_ZN6Assimp11HMPImporterD2Ev:
   79|  3.48k|HMPImporter::~HMPImporter() = default;
_ZNK6Assimp11HMPImporter7GetInfoEv:
   94|  3.48k|const aiImporterDesc *HMPImporter::GetInfo() const {
   95|  3.48k|    return &desc;
   96|  3.48k|}

_ZNK6Assimp11IFCImporter7GetInfoEv:
  131|  3.48k|const aiImporterDesc *IFCImporter::GetInfo() const {
  132|  3.48k|    return &desc;
  133|  3.48k|}

_ZN6Assimp11IFCImporterC2Ev:
   89|  3.48k|    IFCImporter() = default;
_ZN6Assimp11IFCImporter8SettingsC2Ev:
   80|  3.48k|                skipSpaceRepresentations(), useCustomTriangulation(), skipAnnotations(), conicSamplingAngle(10.f), cylindricalTessellation(32) {}

_ZN6Assimp11IQMImporterC2Ev:
   87|  3.48k|        mScene(nullptr) {
   88|       |    // empty
   89|  3.48k|}
_ZNK6Assimp11IQMImporter7GetInfoEv:
  113|  3.48k|const aiImporterDesc *IQMImporter::GetInfo() const {
  114|  3.48k|    return &desc;
  115|  3.48k|}

_ZN6Assimp11IRRImporterC2Ev:
   85|  3.48k|        fps(), configSpeedFlag() {
   86|       |    // empty
   87|  3.48k|}
_ZN6Assimp11IRRImporterD2Ev:
   91|  3.48k|IRRImporter::~IRRImporter() = default;
_ZNK6Assimp11IRRImporter7GetInfoEv:
  101|  3.48k|const aiImporterDesc *IRRImporter::GetInfo() const {
  102|  3.48k|    return &desc;
  103|  3.48k|}

_ZNK6Assimp15IRRMeshImporter7GetInfoEv:
   86|  3.48k|const aiImporterDesc *IRRMeshImporter::GetInfo() const {
   87|  3.48k|    return &desc;
   88|  3.48k|}

_ZN6Assimp15IRRMeshImporterC2Ev:
   66|  3.48k|    IRRMeshImporter() = default;
_ZN6Assimp15IRRMeshImporterD2Ev:
   69|  3.48k|    ~IRRMeshImporter() override = default;

_ZN6Assimp12IrrlichtBaseC2Ev:
   61|  6.97k|    IrrlichtBase() {
   62|       |        // empty
   63|  6.97k|    }
_ZN6Assimp12IrrlichtBaseD2Ev:
   65|  6.97k|    ~IrrlichtBase() = default;

_ZNK6Assimp11LWOImporter7GetInfoEv:
  101|  3.48k|const aiImporterDesc *LWOImporter::GetInfo() const {
  102|  3.48k|    return &desc;
  103|  3.48k|}

_ZN6Assimp11LWOImporterC2Ev:
   77|  3.48k|    LWOImporter() = default;
_ZN6Assimp11LWOImporterD2Ev:
   82|  3.48k|    ~LWOImporter() override = default;

_ZN6Assimp11LWSImporterC2Ev:
  145|  3.48k|        noSkeletonMesh() {
  146|       |    // nothing to do here
  147|  3.48k|}
_ZNK6Assimp11LWSImporter7GetInfoEv:
  161|  3.48k|const aiImporterDesc *LWSImporter::GetInfo() const {
  162|  3.48k|    return &desc;
  163|  3.48k|}

_ZN6Assimp11MD2ImporterC2Ev:
   98|  3.48k|{}
_ZNK6Assimp11MD2Importer7GetInfoEv:
  111|  3.48k|{
  112|  3.48k|    return &desc;
  113|  3.48k|}

_ZN6Assimp11MD3ImporterC2Ev:
  344|  3.48k|        configFrameID(0), configHandleMP(true), configSpeedFlag(), pcHeader(), mBuffer(), fileSize(), mScene(), mIOHandler() {}
_ZN6Assimp11MD3ImporterD2Ev:
  348|  3.48k|MD3Importer::~MD3Importer() = default;
_ZNK6Assimp11MD3Importer7GetInfoEv:
  431|  3.48k|const aiImporterDesc *MD3Importer::GetInfo() const {
  432|  3.48k|    return &desc;
  433|  3.48k|}

_ZN6Assimp11MD5ImporterC2Ev:
   83|  3.48k|        mIOHandler(nullptr),
   84|       |        mBuffer(),
   85|       |        mFileSize(),
   86|       |        mLineNumber(),
   87|       |        mScene(),
   88|       |        mHadMD5Mesh(),
   89|       |        mHadMD5Anim(),
   90|       |        mHadMD5Camera(),
   91|  3.48k|        mCconfigNoAutoLoad(false) {
   92|       |    // empty
   93|  3.48k|}
_ZNK6Assimp11MD5Importer7GetInfoEv:
  104|  3.48k|const aiImporterDesc *MD5Importer::GetInfo() const {
  105|  3.48k|    return &desc;
  106|  3.48k|}

_ZN6Assimp11MD5ImporterD2Ev:
   68|  3.48k|    ~MD5Importer() override = default;

_ZN6Assimp11MDCImporterC2Ev:
  102|  3.48k|        fileSize() {
  103|       |    // empty
  104|  3.48k|}
_ZNK6Assimp11MDCImporter7GetInfoEv:
  114|  3.48k|const aiImporterDesc *MDCImporter::GetInfo() const {
  115|  3.48k|    return &desc;
  116|  3.48k|}

_ZN6Assimp3MDL8HalfLife17HL1ImportSettingsC2Ev:
   57|  6.97k|        read_animations(false),
   58|  6.97k|        read_animation_events(false),
   59|  6.97k|        read_blend_controllers(false),
   60|  6.97k|        read_sequence_groups_info(false),
   61|  6.97k|        read_sequence_transitions(false),
   62|  6.97k|        read_attachments(false),
   63|  6.97k|        read_bone_controllers(false),
   64|  6.97k|        read_hitboxes(false),
   65|  6.97k|        read_textures(false),
   66|  6.97k|        read_misc_global_info(false),
   67|  6.97k|        transform_coord_system(true) {
   68|  6.97k|    }

_ZN6Assimp11MDLImporterC2Ev:
   96|  6.97k|        configFrameID(), mBuffer(), iGSFileVersion(), mIOHandler(nullptr), pScene(), iFileSize() {
   97|       |    // empty
   98|  6.97k|}
_ZNK6Assimp11MDLImporter7GetInfoEv:
  147|  3.48k|const aiImporterDesc *MDLImporter::GetInfo() const {
  148|  3.48k|    return &desc;
  149|  3.48k|}

_ZN6Assimp11MDLImporterD2Ev:
   87|  6.97k|    ~MDLImporter() override = default;

_ZN6Assimp11MMDImporterC2Ev:
   78|  3.48k|        m_Buffer(),
   79|  3.48k|        m_strAbsPath() {
   80|  3.48k|    DefaultIOSystem io;
   81|  3.48k|    m_strAbsPath = io.getOsSeparator();
   82|  3.48k|}
_ZNK6Assimp11MMDImporter7GetInfoEv:
   93|  3.48k|const aiImporterDesc *MMDImporter::GetInfo() const {
   94|  3.48k|    return &desc;
   95|  3.48k|}

_ZN6Assimp11MMDImporterD2Ev:
   62|  3.48k|    ~MMDImporter() override = default;

_ZN6Assimp12MS3DImporterC2Ev:
   81|  3.48k|{}
_ZNK6Assimp12MS3DImporter7GetInfoEv:
   93|  3.48k|{
   94|  3.48k|    return &desc;
   95|  3.48k|}

_ZNK6Assimp11NDOImporter7GetInfoEv:
   83|  3.48k|{
   84|  3.48k|    return &desc;
   85|  3.48k|}

_ZN6Assimp11NDOImporterC2Ev:
   68|  3.48k|    NDOImporter() = default;

_ZNK6Assimp11NFFImporter7GetInfoEv:
   82|  3.48k|const aiImporterDesc *NFFImporter::GetInfo() const {
   83|  3.48k|    return &desc;
   84|  3.48k|}

_ZN6Assimp11NFFImporterC2Ev:
   65|  3.48k|    NFFImporter() = default;

_ZNK6Assimp11OFFImporter7GetInfoEv:
   81|  3.48k|const aiImporterDesc *OFFImporter::GetInfo() const {
   82|  3.48k|    return &desc;
   83|  3.48k|}

_ZN6Assimp11OFFImporterC2Ev:
   60|  3.48k|    OFFImporter() = default;

_ZN6Assimp15ObjFileImporterC2Ev:
   79|  3.48k|        m_Buffer(),
   80|  3.48k|        m_pRootObject(nullptr),
   81|  3.48k|        m_strAbsPath(std::string(1, DefaultIOSystem().getOsSeparator())) {
   82|       |    // empty
   83|  3.48k|}
_ZN6Assimp15ObjFileImporterD2Ev:
   87|  3.48k|ObjFileImporter::~ObjFileImporter() {
   88|  3.48k|    delete m_pRootObject;
   89|  3.48k|}
_ZNK6Assimp15ObjFileImporter7GetInfoEv:
   99|  3.48k|const aiImporterDesc *ObjFileImporter::GetInfo() const {
  100|  3.48k|    return &desc;
  101|  3.48k|}

_ZNK6Assimp4Ogre12OgreImporter7GetInfoEv:
   67|  3.48k|const aiImporterDesc *OgreImporter::GetInfo() const {
   68|  3.48k|    return &desc;
   69|  3.48k|}

_ZN6Assimp7OpenGEX15OpenGEXImporter15VertexContainerC2Ev:
  239|  3.48k|        m_numColors(0), m_colors(nullptr), m_numUVComps(), m_textureCoords() {
  ------------------
  |  |   59|  3.48k|#define nullptr nullptr
  ------------------
  240|       |    // empty
  241|  3.48k|}
_ZN6Assimp7OpenGEX15OpenGEXImporter15VertexContainerD2Ev:
  244|  3.48k|OpenGEXImporter::VertexContainer::~VertexContainer() {
  245|  3.48k|    delete[] m_colors;
  246|       |
  247|  27.9k|    for (auto &texcoords : m_textureCoords) {
  ------------------
  |  Branch (247:26): [True: 27.9k, False: 3.48k]
  ------------------
  248|  27.9k|        delete[] texcoords;
  249|  27.9k|    }
  250|  3.48k|}
_ZN6Assimp7OpenGEX15OpenGEXImporterC2Ev:
  262|  3.48k|        m_root(nullptr),
  ------------------
  |  |   59|  3.48k|#define nullptr nullptr
  ------------------
  263|  3.48k|        m_nodeChildMap(),
  264|  3.48k|        m_mesh2refMap(),
  265|  3.48k|        m_material2refMap(),
  266|  3.48k|        m_ctx(nullptr),
  ------------------
  |  |   59|  3.48k|#define nullptr nullptr
  ------------------
  267|  3.48k|        m_metrics(),
  268|  3.48k|        m_currentNode(nullptr),
  ------------------
  |  |   59|  3.48k|#define nullptr nullptr
  ------------------
  269|  3.48k|        m_currentVertices(),
  270|  3.48k|        m_currentMesh(nullptr),
  ------------------
  |  |   59|  3.48k|#define nullptr nullptr
  ------------------
  271|  3.48k|        m_currentMaterial(nullptr),
  ------------------
  |  |   59|  3.48k|#define nullptr nullptr
  ------------------
  272|  3.48k|        m_currentLight(nullptr),
  ------------------
  |  |   59|  3.48k|#define nullptr nullptr
  ------------------
  273|  3.48k|        m_currentCamera(nullptr),
  ------------------
  |  |   59|  3.48k|#define nullptr nullptr
  ------------------
  274|  3.48k|        m_tokenType(Grammar::NoneType),
  275|  3.48k|        m_materialCache(),
  276|  3.48k|        m_cameraCache(),
  277|  3.48k|        m_lightCache(),
  278|  3.48k|        m_nodeStack(),
  279|  3.48k|        m_unresolvedRefStack() {
  280|       |    // empty
  281|  3.48k|}
_ZNK6Assimp7OpenGEX15OpenGEXImporter7GetInfoEv:
  321|  3.48k|const aiImporterDesc *OpenGEXImporter::GetInfo() const {
  322|  3.48k|    return &desc;
  323|  3.48k|}

_ZN6Assimp7OpenGEX10MetricInfoC2Ev:
   81|  13.9k|    MetricInfo(): m_stringValue( ), m_floatValue( 0.0f ), m_intValue( -1 ) {}
_ZN6Assimp7OpenGEX15OpenGEXImporterD2Ev:
   94|  3.48k|    ~OpenGEXImporter() override = default;

_ZN6Assimp11PLYImporterD2Ev:
  172|  3.48k|    PLYImporter::~PLYImporter() {
  173|  3.48k|        delete mGeneratedMesh;
  174|  3.48k|    }
_ZNK6Assimp11PLYImporter7GetInfoEv:
  184|  3.48k|    const aiImporterDesc *PLYImporter::GetInfo() const {
  185|  3.48k|        return &desc;
  186|  3.48k|    }

_ZN6Assimp11PLYImporterC2Ev:
   68|  3.48k|    PLYImporter() = default;

_ZN6Assimp17Q3BSPFileImporterC2Ev:
  137|  3.48k|        m_pCurrentMesh(nullptr), m_pCurrentFace(nullptr) {
  138|       |    // empty
  139|  3.48k|}
_ZN6Assimp17Q3BSPFileImporterD2Ev:
  143|  3.48k|Q3BSPFileImporter::~Q3BSPFileImporter() {
  144|  3.48k|    clear();
  145|  3.48k|}
_ZN6Assimp17Q3BSPFileImporter5clearEv:
  148|  3.48k|void Q3BSPFileImporter::clear() {
  149|  3.48k|    for (FaceMap::iterator it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); ++it) {
  ------------------
  |  Branch (149:62): [True: 0, False: 3.48k]
  ------------------
  150|      0|        const std::string &matName = it->first;
  151|      0|        if (!matName.empty()) {
  ------------------
  |  Branch (151:13): [True: 0, False: 0]
  ------------------
  152|      0|            delete it->second;
  153|      0|        }
  154|      0|    }
  155|  3.48k|}
_ZNK6Assimp17Q3BSPFileImporter7GetInfoEv:
  168|  3.48k|const aiImporterDesc *Q3BSPFileImporter::GetInfo() const {
  169|  3.48k|    return &desc;
  170|  3.48k|}

_ZN6Assimp11Q3DImporterC2Ev:
   77|  3.48k|Q3DImporter::Q3DImporter() = default;
_ZN6Assimp11Q3DImporterD2Ev:
   81|  3.48k|Q3DImporter::~Q3DImporter() = default;
_ZNK6Assimp11Q3DImporter7GetInfoEv:
   91|  3.48k|const aiImporterDesc *Q3DImporter::GetInfo() const {
   92|  3.48k|    return &desc;
   93|  3.48k|}

_ZNK6Assimp11RAWImporter7GetInfoEv:
   80|  3.48k|const aiImporterDesc *RAWImporter::GetInfo() const {
   81|  3.48k|    return &desc;
   82|  3.48k|}

_ZN6Assimp11RAWImporterC2Ev:
   60|  3.48k|    RAWImporter() = default;

_ZNK6Assimp11SIBImporter7GetInfoEv:
  206|  3.48k|const aiImporterDesc *SIBImporter::GetInfo() const {
  207|  3.48k|    return &desc;
  208|  3.48k|}

_ZN6Assimp11SIBImporterC2Ev:
   60|  3.48k|    SIBImporter() = default;

_ZN6Assimp11SMDImporterC2Ev:
   86|  3.48k|        mBuffer(),
   87|  3.48k|        mEnd(nullptr),
   88|  3.48k|        pScene(nullptr),
   89|  3.48k|        iFileSize( 0 ),
   90|  3.48k|        iSmallestFrame( INT_MAX ),
   91|  3.48k|        dLengthOfAnim( 0.0 ),
   92|  3.48k|        bHasUVs(false ),
   93|  3.48k|        iLineNumber((unsigned int)-1)  {
   94|       |    // empty
   95|  3.48k|}
_ZNK6Assimp11SMDImporter7GetInfoEv:
  106|  3.48k|const aiImporterDesc* SMDImporter::GetInfo () const {
  107|  3.48k|    return &desc;
  108|  3.48k|}

_ZN6Assimp11SMDImporterD2Ev:
  165|  3.48k|    ~SMDImporter() override = default;

_ZN6Assimp11STLImporterC2Ev:
  130|  3.48k|        mFileSize(0),
  131|  3.48k|        mScene() {
  132|       |    // empty
  133|  3.48k|}
_ZN6Assimp11STLImporterD2Ev:
  137|  3.48k|STLImporter::~STLImporter() = default;
_ZNK6Assimp11STLImporter7GetInfoEv:
  147|  3.48k|const aiImporterDesc *STLImporter::GetInfo() const {
  148|  3.48k|    return &desc;
  149|  3.48k|}

_ZN6Assimp4STEP7EXPRESS16ConversionSchema11SchemaEntryC2EPKcPFPNS0_6ObjectERKNS0_2DBERKNS1_4LISTEE:
  321|  1.96k|        SchemaEntry(const char *name, ConvertObjectProc func) : mName(name), mFunc(func) {}

_ZN6Assimp16TerragenImporterC2Ev:
   72|  3.48k|        configComputeUVs(false) {
   73|       |    // empty
   74|  3.48k|}
_ZNK6Assimp16TerragenImporter7GetInfoEv:
   85|  3.48k|const aiImporterDesc *TerragenImporter::GetInfo() const {
   86|  3.48k|    return &desc;
   87|  3.48k|}

_ZN6Assimp14UnrealImporterC2Ev:
  166|  3.48k|        mConfigFrameID(0), mConfigHandleFlags(true) {
  167|       |    // empty
  168|  3.48k|}
_ZNK6Assimp14UnrealImporter7GetInfoEv:
  178|  3.48k|const aiImporterDesc *UnrealImporter::GetInfo() const {
  179|  3.48k|    return &desc;
  180|  3.48k|}

_ZNK6Assimp13XFileImporter7GetInfoEv:
   86|  3.48k|const aiImporterDesc *XFileImporter::GetInfo() const {
   87|  3.48k|    return &desc;
   88|  3.48k|}

_ZN6Assimp13XFileImporterC2Ev:
   71|  3.48k|    XFileImporter() = default;
_ZN6Assimp13XFileImporterD2Ev:
   72|  3.48k|    ~XFileImporter() override = default;

_ZN6Assimp11X3DImporterC2Ev:
  192|  3.48k|        mNodeElementCur(nullptr),
  193|  3.48k|        mScene(nullptr),
  194|  3.48k|        mpIOHandler(nullptr) {
  195|       |    // empty
  196|  3.48k|}
_ZN6Assimp11X3DImporterD2Ev:
  198|  3.48k|X3DImporter::~X3DImporter() {
  199|       |    // Clear() is accounting if data already is deleted. So, just check again if all data is deleted.
  200|  3.48k|    Clear();
  201|  3.48k|}
_ZN6Assimp11X3DImporter5ClearEv:
  203|  3.48k|void X3DImporter::Clear() {
  204|  3.48k|    mNodeElementCur = nullptr;
  205|       |    // Delete all elements
  206|  3.48k|    if (!NodeElement_List.empty()) {
  ------------------
  |  Branch (206:9): [True: 0, False: 3.48k]
  ------------------
  207|      0|        for (std::list<X3DNodeElementBase *>::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); ++it) {
  ------------------
  |  Branch (207:87): [True: 0, False: 0]
  ------------------
  208|      0|            delete *it;
  209|      0|        }
  210|      0|        NodeElement_List.clear();
  211|      0|    }
  212|  3.48k|}
_ZNK6Assimp11X3DImporter7GetInfoEv:
  340|  3.48k|const aiImporterDesc *X3DImporter::GetInfo() const {
  341|  3.48k|    return &Description;
  342|  3.48k|}

_ZN6Assimp11XGLImporterC2Ev:
   75|  3.48k|XGLImporter::XGLImporter() : mXmlParser(nullptr), m_scene(nullptr) {
   76|       |    // empty
   77|  3.48k|}
_ZN6Assimp11XGLImporterD2Ev:
   80|  3.48k|XGLImporter::~XGLImporter() {
   81|  3.48k|    clear();
   82|  3.48k|}
_ZNK6Assimp11XGLImporter7GetInfoEv:
   91|  3.48k|const aiImporterDesc *XGLImporter::GetInfo() const {
   92|  3.48k|	return &desc;
   93|  3.48k|}
_ZN6Assimp11XGLImporter5clearEv:
  170|  3.48k|void XGLImporter::clear() {
  171|  3.48k|    delete mXmlParser;
  172|  3.48k|    mXmlParser = nullptr;
  173|  3.48k|}

_ZN4glTF6ObjectD2Ev:
  312|  2.44k|    virtual ~Object() = default;
_ZN4glTF5AssetC2EPN6Assimp8IOSystemE:
  966|  4.58k|            mIOSystem(io),
  967|  4.58k|            asset(),
  968|  4.58k|            accessors(*this, "accessors"),
  969|  4.58k|            animations(*this, "animations"),
  970|  4.58k|            buffers(*this, "buffers"),
  971|  4.58k|            bufferViews(*this, "bufferViews"),
  972|  4.58k|            cameras(*this, "cameras"),
  973|  4.58k|            images(*this, "images"),
  974|  4.58k|            materials(*this, "materials"),
  975|  4.58k|            meshes(*this, "meshes"),
  976|  4.58k|            nodes(*this, "nodes"),
  977|  4.58k|            samplers(*this, "samplers"),
  978|  4.58k|            scenes(*this, "scenes"),
  979|  4.58k|            skins(*this, "skins"),
  980|  4.58k|            textures(*this, "textures"),
  981|  4.58k|            lights(*this, "lights", "KHR_materials_common") {
  982|  4.58k|        memset(&extensionsUsed, 0, sizeof(extensionsUsed));
  983|  4.58k|    }
_ZN4glTF13AssetMetadataC2Ev:
  898|  4.58k|            premultipliedAlpha(false) {
  899|  4.58k|    }
_ZN4glTF12LazyDictBaseD2Ev:
  825|  64.2k|    virtual ~LazyDictBase() = default;
_ZN4glTF6ObjectC2Ev:
  311|  2.44k|    Object() = default;
_ZN4glTF6Buffer13MarkAsSpecialEv:
  484|  2.44k|    void MarkAsSpecial() { mIsSpecial = true; }
_ZNK4glTF13AssetMetadatacvbEv:
  901|  1.38k|    operator bool() const { return version.size() && version[0] == '1'; }
  ------------------
  |  Branch (901:36): [True: 1.05k, False: 328]
  |  Branch (901:54): [True: 285, False: 768]
  ------------------
_ZNK4glTF8LazyDictINS_8MaterialEE4SizeEv:
  878|     89|    inline unsigned int Size() const { return unsigned(mObjs.size()); }
_ZNK4glTF8LazyDictINS_4MeshEE4SizeEv:
  878|     89|    inline unsigned int Size() const { return unsigned(mObjs.size()); }
_ZNK4glTF8LazyDictINS_6CameraEE4SizeEv:
  878|     89|    inline unsigned int Size() const { return unsigned(mObjs.size()); }
_ZNK4glTF8LazyDictINS_5LightEE4SizeEv:
  878|     89|    inline unsigned int Size() const { return unsigned(mObjs.size()); }
_ZNK4glTF8LazyDictINS_5ImageEE4SizeEv:
  878|    178|    inline unsigned int Size() const { return unsigned(mObjs.size()); }

_ZN4glTF6BufferD2Ev:
  166|  2.44k|inline Buffer::~Buffer() {
  167|  2.44k|    for (SEncodedRegion *reg : EncodedRegion_List)
  ------------------
  |  Branch (167:30): [True: 0, False: 2.44k]
  ------------------
  168|      0|        delete reg;
  169|  2.44k|}
_ZN4glTF8LazyDictINS_8AccessorEEC2ERNS_5AssetEPKcS6_:
   71|  4.58k|        mDictId(dictId), mExtId(extId), mDict(nullptr), mAsset(asset) {
   72|  4.58k|    asset.mDicts.push_back(this); // register to the list of dictionaries
   73|  4.58k|}
_ZN4glTF8LazyDictINS_8AccessorEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
   83|    192|inline void LazyDict<T>::AttachToDocument(Document &doc) {
   84|    192|    Value *container = nullptr;
   85|       |
   86|    192|    if (mExtId) {
  ------------------
  |  Branch (86:9): [True: 0, False: 192]
  ------------------
   87|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (87:20): [True: 0, False: 0]
  ------------------
   88|      0|            container = FindObject(*exts, mExtId);
   89|      0|        }
   90|    192|    } else {
   91|    192|        container = &doc;
   92|    192|    }
   93|       |
   94|    192|    if (container) {
  ------------------
  |  Branch (94:9): [True: 192, False: 0]
  ------------------
   95|    192|        mDict = FindObject(*container, mDictId);
   96|    192|    }
   97|    192|}
_ZN4glTF8LazyDictINS_8AccessorEE18DetachFromDocumentEv:
  100|    178|inline void LazyDict<T>::DetachFromDocument() {
  101|    178|    mDict = nullptr;
  102|    178|}
_ZN4glTF8LazyDictINS_9AnimationEEC2ERNS_5AssetEPKcS6_:
   71|  4.58k|        mDictId(dictId), mExtId(extId), mDict(nullptr), mAsset(asset) {
   72|  4.58k|    asset.mDicts.push_back(this); // register to the list of dictionaries
   73|  4.58k|}
_ZN4glTF8LazyDictINS_9AnimationEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
   83|    192|inline void LazyDict<T>::AttachToDocument(Document &doc) {
   84|    192|    Value *container = nullptr;
   85|       |
   86|    192|    if (mExtId) {
  ------------------
  |  Branch (86:9): [True: 0, False: 192]
  ------------------
   87|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (87:20): [True: 0, False: 0]
  ------------------
   88|      0|            container = FindObject(*exts, mExtId);
   89|      0|        }
   90|    192|    } else {
   91|    192|        container = &doc;
   92|    192|    }
   93|       |
   94|    192|    if (container) {
  ------------------
  |  Branch (94:9): [True: 192, False: 0]
  ------------------
   95|    192|        mDict = FindObject(*container, mDictId);
   96|    192|    }
   97|    192|}
_ZN4glTF8LazyDictINS_9AnimationEE18DetachFromDocumentEv:
  100|    178|inline void LazyDict<T>::DetachFromDocument() {
  101|    178|    mDict = nullptr;
  102|    178|}
_ZN4glTF8LazyDictINS_6BufferEEC2ERNS_5AssetEPKcS6_:
   71|  4.58k|        mDictId(dictId), mExtId(extId), mDict(nullptr), mAsset(asset) {
   72|  4.58k|    asset.mDicts.push_back(this); // register to the list of dictionaries
   73|  4.58k|}
_ZN4glTF8LazyDictINS_6BufferEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
   83|    192|inline void LazyDict<T>::AttachToDocument(Document &doc) {
   84|    192|    Value *container = nullptr;
   85|       |
   86|    192|    if (mExtId) {
  ------------------
  |  Branch (86:9): [True: 0, False: 192]
  ------------------
   87|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (87:20): [True: 0, False: 0]
  ------------------
   88|      0|            container = FindObject(*exts, mExtId);
   89|      0|        }
   90|    192|    } else {
   91|    192|        container = &doc;
   92|    192|    }
   93|       |
   94|    192|    if (container) {
  ------------------
  |  Branch (94:9): [True: 192, False: 0]
  ------------------
   95|    192|        mDict = FindObject(*container, mDictId);
   96|    192|    }
   97|    192|}
_ZN4glTF8LazyDictINS_6BufferEE18DetachFromDocumentEv:
  100|    178|inline void LazyDict<T>::DetachFromDocument() {
  101|    178|    mDict = nullptr;
  102|    178|}
_ZN4glTF8LazyDictINS_10BufferViewEEC2ERNS_5AssetEPKcS6_:
   71|  4.58k|        mDictId(dictId), mExtId(extId), mDict(nullptr), mAsset(asset) {
   72|  4.58k|    asset.mDicts.push_back(this); // register to the list of dictionaries
   73|  4.58k|}
_ZN4glTF8LazyDictINS_10BufferViewEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
   83|    192|inline void LazyDict<T>::AttachToDocument(Document &doc) {
   84|    192|    Value *container = nullptr;
   85|       |
   86|    192|    if (mExtId) {
  ------------------
  |  Branch (86:9): [True: 0, False: 192]
  ------------------
   87|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (87:20): [True: 0, False: 0]
  ------------------
   88|      0|            container = FindObject(*exts, mExtId);
   89|      0|        }
   90|    192|    } else {
   91|    192|        container = &doc;
   92|    192|    }
   93|       |
   94|    192|    if (container) {
  ------------------
  |  Branch (94:9): [True: 192, False: 0]
  ------------------
   95|    192|        mDict = FindObject(*container, mDictId);
   96|    192|    }
   97|    192|}
_ZN4glTF8LazyDictINS_10BufferViewEE18DetachFromDocumentEv:
  100|    178|inline void LazyDict<T>::DetachFromDocument() {
  101|    178|    mDict = nullptr;
  102|    178|}
_ZN4glTF8LazyDictINS_6CameraEEC2ERNS_5AssetEPKcS6_:
   71|  4.58k|        mDictId(dictId), mExtId(extId), mDict(nullptr), mAsset(asset) {
   72|  4.58k|    asset.mDicts.push_back(this); // register to the list of dictionaries
   73|  4.58k|}
_ZN4glTF8LazyDictINS_6CameraEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
   83|    192|inline void LazyDict<T>::AttachToDocument(Document &doc) {
   84|    192|    Value *container = nullptr;
   85|       |
   86|    192|    if (mExtId) {
  ------------------
  |  Branch (86:9): [True: 0, False: 192]
  ------------------
   87|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (87:20): [True: 0, False: 0]
  ------------------
   88|      0|            container = FindObject(*exts, mExtId);
   89|      0|        }
   90|    192|    } else {
   91|    192|        container = &doc;
   92|    192|    }
   93|       |
   94|    192|    if (container) {
  ------------------
  |  Branch (94:9): [True: 192, False: 0]
  ------------------
   95|    192|        mDict = FindObject(*container, mDictId);
   96|    192|    }
   97|    192|}
_ZN4glTF8LazyDictINS_6CameraEE18DetachFromDocumentEv:
  100|    178|inline void LazyDict<T>::DetachFromDocument() {
  101|    178|    mDict = nullptr;
  102|    178|}
_ZN4glTF8LazyDictINS_5ImageEEC2ERNS_5AssetEPKcS6_:
   71|  4.58k|        mDictId(dictId), mExtId(extId), mDict(nullptr), mAsset(asset) {
   72|  4.58k|    asset.mDicts.push_back(this); // register to the list of dictionaries
   73|  4.58k|}
_ZN4glTF8LazyDictINS_5ImageEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
   83|    192|inline void LazyDict<T>::AttachToDocument(Document &doc) {
   84|    192|    Value *container = nullptr;
   85|       |
   86|    192|    if (mExtId) {
  ------------------
  |  Branch (86:9): [True: 0, False: 192]
  ------------------
   87|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (87:20): [True: 0, False: 0]
  ------------------
   88|      0|            container = FindObject(*exts, mExtId);
   89|      0|        }
   90|    192|    } else {
   91|    192|        container = &doc;
   92|    192|    }
   93|       |
   94|    192|    if (container) {
  ------------------
  |  Branch (94:9): [True: 192, False: 0]
  ------------------
   95|    192|        mDict = FindObject(*container, mDictId);
   96|    192|    }
   97|    192|}
_ZN4glTF8LazyDictINS_5ImageEE18DetachFromDocumentEv:
  100|    178|inline void LazyDict<T>::DetachFromDocument() {
  101|    178|    mDict = nullptr;
  102|    178|}
_ZN4glTF8LazyDictINS_8MaterialEEC2ERNS_5AssetEPKcS6_:
   71|  4.58k|        mDictId(dictId), mExtId(extId), mDict(nullptr), mAsset(asset) {
   72|  4.58k|    asset.mDicts.push_back(this); // register to the list of dictionaries
   73|  4.58k|}
_ZN4glTF8LazyDictINS_8MaterialEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
   83|    192|inline void LazyDict<T>::AttachToDocument(Document &doc) {
   84|    192|    Value *container = nullptr;
   85|       |
   86|    192|    if (mExtId) {
  ------------------
  |  Branch (86:9): [True: 0, False: 192]
  ------------------
   87|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (87:20): [True: 0, False: 0]
  ------------------
   88|      0|            container = FindObject(*exts, mExtId);
   89|      0|        }
   90|    192|    } else {
   91|    192|        container = &doc;
   92|    192|    }
   93|       |
   94|    192|    if (container) {
  ------------------
  |  Branch (94:9): [True: 192, False: 0]
  ------------------
   95|    192|        mDict = FindObject(*container, mDictId);
   96|    192|    }
   97|    192|}
_ZN4glTF8LazyDictINS_8MaterialEE18DetachFromDocumentEv:
  100|    178|inline void LazyDict<T>::DetachFromDocument() {
  101|    178|    mDict = nullptr;
  102|    178|}
_ZN4glTF8LazyDictINS_4MeshEEC2ERNS_5AssetEPKcS6_:
   71|  4.58k|        mDictId(dictId), mExtId(extId), mDict(nullptr), mAsset(asset) {
   72|  4.58k|    asset.mDicts.push_back(this); // register to the list of dictionaries
   73|  4.58k|}
_ZN4glTF8LazyDictINS_4MeshEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
   83|    192|inline void LazyDict<T>::AttachToDocument(Document &doc) {
   84|    192|    Value *container = nullptr;
   85|       |
   86|    192|    if (mExtId) {
  ------------------
  |  Branch (86:9): [True: 0, False: 192]
  ------------------
   87|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (87:20): [True: 0, False: 0]
  ------------------
   88|      0|            container = FindObject(*exts, mExtId);
   89|      0|        }
   90|    192|    } else {
   91|    192|        container = &doc;
   92|    192|    }
   93|       |
   94|    192|    if (container) {
  ------------------
  |  Branch (94:9): [True: 192, False: 0]
  ------------------
   95|    192|        mDict = FindObject(*container, mDictId);
   96|    192|    }
   97|    192|}
_ZN4glTF8LazyDictINS_4MeshEE18DetachFromDocumentEv:
  100|    178|inline void LazyDict<T>::DetachFromDocument() {
  101|    178|    mDict = nullptr;
  102|    178|}
_ZN4glTF8LazyDictINS_4NodeEEC2ERNS_5AssetEPKcS6_:
   71|  4.58k|        mDictId(dictId), mExtId(extId), mDict(nullptr), mAsset(asset) {
   72|  4.58k|    asset.mDicts.push_back(this); // register to the list of dictionaries
   73|  4.58k|}
_ZN4glTF8LazyDictINS_4NodeEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
   83|    192|inline void LazyDict<T>::AttachToDocument(Document &doc) {
   84|    192|    Value *container = nullptr;
   85|       |
   86|    192|    if (mExtId) {
  ------------------
  |  Branch (86:9): [True: 0, False: 192]
  ------------------
   87|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (87:20): [True: 0, False: 0]
  ------------------
   88|      0|            container = FindObject(*exts, mExtId);
   89|      0|        }
   90|    192|    } else {
   91|    192|        container = &doc;
   92|    192|    }
   93|       |
   94|    192|    if (container) {
  ------------------
  |  Branch (94:9): [True: 192, False: 0]
  ------------------
   95|    192|        mDict = FindObject(*container, mDictId);
   96|    192|    }
   97|    192|}
_ZN4glTF8LazyDictINS_4NodeEE18DetachFromDocumentEv:
  100|    178|inline void LazyDict<T>::DetachFromDocument() {
  101|    178|    mDict = nullptr;
  102|    178|}
_ZN4glTF8LazyDictINS_7SamplerEEC2ERNS_5AssetEPKcS6_:
   71|  4.58k|        mDictId(dictId), mExtId(extId), mDict(nullptr), mAsset(asset) {
   72|  4.58k|    asset.mDicts.push_back(this); // register to the list of dictionaries
   73|  4.58k|}
_ZN4glTF8LazyDictINS_7SamplerEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
   83|    192|inline void LazyDict<T>::AttachToDocument(Document &doc) {
   84|    192|    Value *container = nullptr;
   85|       |
   86|    192|    if (mExtId) {
  ------------------
  |  Branch (86:9): [True: 0, False: 192]
  ------------------
   87|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (87:20): [True: 0, False: 0]
  ------------------
   88|      0|            container = FindObject(*exts, mExtId);
   89|      0|        }
   90|    192|    } else {
   91|    192|        container = &doc;
   92|    192|    }
   93|       |
   94|    192|    if (container) {
  ------------------
  |  Branch (94:9): [True: 192, False: 0]
  ------------------
   95|    192|        mDict = FindObject(*container, mDictId);
   96|    192|    }
   97|    192|}
_ZN4glTF8LazyDictINS_7SamplerEE18DetachFromDocumentEv:
  100|    178|inline void LazyDict<T>::DetachFromDocument() {
  101|    178|    mDict = nullptr;
  102|    178|}
_ZN4glTF8LazyDictINS_5SceneEEC2ERNS_5AssetEPKcS6_:
   71|  4.58k|        mDictId(dictId), mExtId(extId), mDict(nullptr), mAsset(asset) {
   72|  4.58k|    asset.mDicts.push_back(this); // register to the list of dictionaries
   73|  4.58k|}
_ZN4glTF8LazyDictINS_5SceneEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
   83|    192|inline void LazyDict<T>::AttachToDocument(Document &doc) {
   84|    192|    Value *container = nullptr;
   85|       |
   86|    192|    if (mExtId) {
  ------------------
  |  Branch (86:9): [True: 0, False: 192]
  ------------------
   87|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (87:20): [True: 0, False: 0]
  ------------------
   88|      0|            container = FindObject(*exts, mExtId);
   89|      0|        }
   90|    192|    } else {
   91|    192|        container = &doc;
   92|    192|    }
   93|       |
   94|    192|    if (container) {
  ------------------
  |  Branch (94:9): [True: 192, False: 0]
  ------------------
   95|    192|        mDict = FindObject(*container, mDictId);
   96|    192|    }
   97|    192|}
_ZN4glTF8LazyDictINS_5SceneEE18DetachFromDocumentEv:
  100|    178|inline void LazyDict<T>::DetachFromDocument() {
  101|    178|    mDict = nullptr;
  102|    178|}
_ZN4glTF8LazyDictINS_4SkinEEC2ERNS_5AssetEPKcS6_:
   71|  4.58k|        mDictId(dictId), mExtId(extId), mDict(nullptr), mAsset(asset) {
   72|  4.58k|    asset.mDicts.push_back(this); // register to the list of dictionaries
   73|  4.58k|}
_ZN4glTF8LazyDictINS_4SkinEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
   83|    192|inline void LazyDict<T>::AttachToDocument(Document &doc) {
   84|    192|    Value *container = nullptr;
   85|       |
   86|    192|    if (mExtId) {
  ------------------
  |  Branch (86:9): [True: 0, False: 192]
  ------------------
   87|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (87:20): [True: 0, False: 0]
  ------------------
   88|      0|            container = FindObject(*exts, mExtId);
   89|      0|        }
   90|    192|    } else {
   91|    192|        container = &doc;
   92|    192|    }
   93|       |
   94|    192|    if (container) {
  ------------------
  |  Branch (94:9): [True: 192, False: 0]
  ------------------
   95|    192|        mDict = FindObject(*container, mDictId);
   96|    192|    }
   97|    192|}
_ZN4glTF8LazyDictINS_4SkinEE18DetachFromDocumentEv:
  100|    178|inline void LazyDict<T>::DetachFromDocument() {
  101|    178|    mDict = nullptr;
  102|    178|}
_ZN4glTF8LazyDictINS_7TextureEEC2ERNS_5AssetEPKcS6_:
   71|  4.58k|        mDictId(dictId), mExtId(extId), mDict(nullptr), mAsset(asset) {
   72|  4.58k|    asset.mDicts.push_back(this); // register to the list of dictionaries
   73|  4.58k|}
_ZN4glTF8LazyDictINS_7TextureEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
   83|    192|inline void LazyDict<T>::AttachToDocument(Document &doc) {
   84|    192|    Value *container = nullptr;
   85|       |
   86|    192|    if (mExtId) {
  ------------------
  |  Branch (86:9): [True: 0, False: 192]
  ------------------
   87|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (87:20): [True: 0, False: 0]
  ------------------
   88|      0|            container = FindObject(*exts, mExtId);
   89|      0|        }
   90|    192|    } else {
   91|    192|        container = &doc;
   92|    192|    }
   93|       |
   94|    192|    if (container) {
  ------------------
  |  Branch (94:9): [True: 192, False: 0]
  ------------------
   95|    192|        mDict = FindObject(*container, mDictId);
   96|    192|    }
   97|    192|}
_ZN4glTF8LazyDictINS_7TextureEE18DetachFromDocumentEv:
  100|    178|inline void LazyDict<T>::DetachFromDocument() {
  101|    178|    mDict = nullptr;
  102|    178|}
_ZN4glTF8LazyDictINS_5LightEEC2ERNS_5AssetEPKcS6_:
   71|  4.58k|        mDictId(dictId), mExtId(extId), mDict(nullptr), mAsset(asset) {
   72|  4.58k|    asset.mDicts.push_back(this); // register to the list of dictionaries
   73|  4.58k|}
_ZN4glTF8LazyDictINS_5LightEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
   83|    192|inline void LazyDict<T>::AttachToDocument(Document &doc) {
   84|    192|    Value *container = nullptr;
   85|       |
   86|    192|    if (mExtId) {
  ------------------
  |  Branch (86:9): [True: 192, False: 0]
  ------------------
   87|    192|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (87:20): [True: 0, False: 192]
  ------------------
   88|      0|            container = FindObject(*exts, mExtId);
   89|      0|        }
   90|    192|    } else {
   91|      0|        container = &doc;
   92|      0|    }
   93|       |
   94|    192|    if (container) {
  ------------------
  |  Branch (94:9): [True: 0, False: 192]
  ------------------
   95|      0|        mDict = FindObject(*container, mDictId);
   96|      0|    }
   97|    192|}
_ZN4glTF8LazyDictINS_5LightEE18DetachFromDocumentEv:
  100|    178|inline void LazyDict<T>::DetachFromDocument() {
  101|    178|    mDict = nullptr;
  102|    178|}
_ZN4glTF8LazyDictINS_5LightEED2Ev:
   76|  4.58k|inline LazyDict<T>::~LazyDict() {
   77|  4.58k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (77:24): [True: 0, False: 4.58k]
  ------------------
   78|      0|        delete mObjs[i];
   79|      0|    }
   80|  4.58k|}
_ZN4glTF8LazyDictINS_7TextureEED2Ev:
   76|  4.58k|inline LazyDict<T>::~LazyDict() {
   77|  4.58k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (77:24): [True: 0, False: 4.58k]
  ------------------
   78|      0|        delete mObjs[i];
   79|      0|    }
   80|  4.58k|}
_ZN4glTF8LazyDictINS_4SkinEED2Ev:
   76|  4.58k|inline LazyDict<T>::~LazyDict() {
   77|  4.58k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (77:24): [True: 0, False: 4.58k]
  ------------------
   78|      0|        delete mObjs[i];
   79|      0|    }
   80|  4.58k|}
_ZN4glTF8LazyDictINS_5SceneEED2Ev:
   76|  4.58k|inline LazyDict<T>::~LazyDict() {
   77|  4.58k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (77:24): [True: 0, False: 4.58k]
  ------------------
   78|      0|        delete mObjs[i];
   79|      0|    }
   80|  4.58k|}
_ZN4glTF8LazyDictINS_7SamplerEED2Ev:
   76|  4.58k|inline LazyDict<T>::~LazyDict() {
   77|  4.58k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (77:24): [True: 0, False: 4.58k]
  ------------------
   78|      0|        delete mObjs[i];
   79|      0|    }
   80|  4.58k|}
_ZN4glTF8LazyDictINS_4NodeEED2Ev:
   76|  4.58k|inline LazyDict<T>::~LazyDict() {
   77|  4.58k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (77:24): [True: 0, False: 4.58k]
  ------------------
   78|      0|        delete mObjs[i];
   79|      0|    }
   80|  4.58k|}
_ZN4glTF8LazyDictINS_4MeshEED2Ev:
   76|  4.58k|inline LazyDict<T>::~LazyDict() {
   77|  4.58k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (77:24): [True: 0, False: 4.58k]
  ------------------
   78|      0|        delete mObjs[i];
   79|      0|    }
   80|  4.58k|}
_ZN4glTF8LazyDictINS_8MaterialEED2Ev:
   76|  4.58k|inline LazyDict<T>::~LazyDict() {
   77|  4.58k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (77:24): [True: 0, False: 4.58k]
  ------------------
   78|      0|        delete mObjs[i];
   79|      0|    }
   80|  4.58k|}
_ZN4glTF8LazyDictINS_5ImageEED2Ev:
   76|  4.58k|inline LazyDict<T>::~LazyDict() {
   77|  4.58k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (77:24): [True: 0, False: 4.58k]
  ------------------
   78|      0|        delete mObjs[i];
   79|      0|    }
   80|  4.58k|}
_ZN4glTF8LazyDictINS_6CameraEED2Ev:
   76|  4.58k|inline LazyDict<T>::~LazyDict() {
   77|  4.58k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (77:24): [True: 0, False: 4.58k]
  ------------------
   78|      0|        delete mObjs[i];
   79|      0|    }
   80|  4.58k|}
_ZN4glTF8LazyDictINS_10BufferViewEED2Ev:
   76|  4.58k|inline LazyDict<T>::~LazyDict() {
   77|  4.58k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (77:24): [True: 0, False: 4.58k]
  ------------------
   78|      0|        delete mObjs[i];
   79|      0|    }
   80|  4.58k|}
_ZN4glTF8LazyDictINS_6BufferEED2Ev:
   76|  4.58k|inline LazyDict<T>::~LazyDict() {
   77|  7.02k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (77:24): [True: 2.44k, False: 4.58k]
  ------------------
   78|  2.44k|        delete mObjs[i];
   79|  2.44k|    }
   80|  4.58k|}
_ZN4glTF8LazyDictINS_9AnimationEED2Ev:
   76|  4.58k|inline LazyDict<T>::~LazyDict() {
   77|  4.58k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (77:24): [True: 0, False: 4.58k]
  ------------------
   78|      0|        delete mObjs[i];
   79|      0|    }
   80|  4.58k|}
_ZN4glTF8LazyDictINS_8AccessorEED2Ev:
   76|  4.58k|inline LazyDict<T>::~LazyDict() {
   77|  4.58k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (77:24): [True: 0, False: 4.58k]
  ------------------
   78|      0|        delete mObjs[i];
   79|      0|    }
   80|  4.58k|}
_ZN4glTF5Asset4LoadERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEb:
 1156|  4.58k|inline void Asset::Load(const std::string &pFile, bool isBinary) {
 1157|  4.58k|    mCurrentAssetDir.clear();
 1158|       |
 1159|       |    /*int pos = std::max(int(pFile.rfind('/')), int(pFile.rfind('\\')));
 1160|       |    if (pos != int(std::string::npos)) mCurrentAssetDir = pFile.substr(0, pos + 1);*/
 1161|  4.58k|    if (0 != strncmp(pFile.c_str(), AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH)) {
  ------------------
  |  Branch (1161:9): [True: 0, False: 4.58k]
  ------------------
 1162|      0|        mCurrentAssetDir = getCurrentAssetDir(pFile);
 1163|      0|    }
 1164|       |
 1165|  4.58k|    shared_ptr<IOStream> stream(OpenFile(pFile.c_str(), "rb", true));
 1166|  4.58k|    if (!stream) {
  ------------------
  |  Branch (1166:9): [True: 0, False: 4.58k]
  ------------------
 1167|      0|        throw DeadlyImportError("GLTF: Could not open file for reading");
 1168|      0|    }
 1169|       |
 1170|       |    // is binary? then read the header
 1171|  4.58k|    if (isBinary) {
  ------------------
  |  Branch (1171:9): [True: 2.44k, False: 2.14k]
  ------------------
 1172|  2.44k|        SetAsBinary(); // also creates the body buffer
 1173|  2.44k|        ReadBinaryHeader(*stream);
 1174|  2.44k|    } else {
 1175|  2.14k|        mSceneLength = stream->FileSize();
 1176|  2.14k|        mBodyLength = 0;
 1177|  2.14k|    }
 1178|       |
 1179|       |    // Smallest legal JSON file is "{}" Smallest loadable glTF file is larger than that but catch it later
 1180|  4.58k|    if (mSceneLength < 2) {
  ------------------
  |  Branch (1180:9): [True: 0, False: 4.58k]
  ------------------
 1181|      0|        throw DeadlyImportError("GLTF: No JSON file contents");
 1182|      0|    }
 1183|       |
 1184|       |    // Binary format only supports up to 4GB of JSON so limit it there to avoid extreme memory allocation
 1185|  4.58k|    if (mSceneLength >= std::numeric_limits<uint32_t>::max()) {
  ------------------
  |  Branch (1185:9): [True: 0, False: 4.58k]
  ------------------
 1186|      0|        throw DeadlyImportError("GLTF: JSON size greater than 4GB");
 1187|      0|    }
 1188|       |
 1189|       |    // read the scene data, ensure null termination
 1190|  4.58k|    std::vector<char> sceneData(mSceneLength + 1);
 1191|  4.58k|    sceneData[mSceneLength] = '\0';
 1192|       |
 1193|  4.58k|    if (stream->Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
  ------------------
  |  Branch (1193:9): [True: 24, False: 4.56k]
  ------------------
 1194|     24|        throw DeadlyImportError("GLTF: Could not read the file contents");
 1195|     24|    }
 1196|       |
 1197|       |    // parse the JSON document
 1198|       |
 1199|  4.56k|    Document doc;
 1200|  4.56k|    doc.ParseInsitu(&sceneData[0]);
 1201|       |
 1202|  4.56k|    if (doc.HasParseError()) {
  ------------------
  |  Branch (1202:9): [True: 1.45k, False: 3.10k]
  ------------------
 1203|  1.45k|        char buffer[32];
 1204|  1.45k|        ai_snprintf(buffer, 32, "%d", static_cast<int>(doc.GetErrorOffset()));
 1205|  1.45k|        throw DeadlyImportError("GLTF: JSON parse error, offset ", buffer, ": ", GetParseError_En(doc.GetParseError()));
 1206|  1.45k|    }
 1207|       |
 1208|  3.10k|    if (!doc.IsObject()) {
  ------------------
  |  Branch (1208:9): [True: 78, False: 3.02k]
  ------------------
 1209|     78|        throw DeadlyImportError("GLTF: JSON document root must be a JSON object");
 1210|     78|    }
 1211|       |
 1212|       |    // Fill the buffer instance for the current file embedded contents
 1213|  3.02k|    if (mBodyLength > 0) {
  ------------------
  |  Branch (1213:9): [True: 0, False: 3.02k]
  ------------------
 1214|      0|        if (!mBodyBuffer->LoadFromStream(*stream, mBodyLength, mBodyOffset)) {
  ------------------
  |  Branch (1214:13): [True: 0, False: 0]
  ------------------
 1215|      0|            throw DeadlyImportError("GLTF: Unable to read gltf file");
 1216|      0|        }
 1217|      0|    }
 1218|       |
 1219|       |    // Load the metadata
 1220|  3.02k|    asset.Read(doc);
 1221|  3.02k|    if (!asset) {
  ------------------
  |  Branch (1221:9): [True: 548, False: 2.48k]
  ------------------
 1222|    548|        return;
 1223|    548|    }
 1224|       |
 1225|  2.48k|    ReadExtensionsUsed(doc);
 1226|       |
 1227|       |    // Prepare the dictionaries
 1228|  5.16k|    for (size_t i = 0; i < mDicts.size(); ++i) {
  ------------------
  |  Branch (1228:24): [True: 2.68k, False: 2.48k]
  ------------------
 1229|  2.68k|        mDicts[i]->AttachToDocument(doc);
 1230|  2.68k|    }
 1231|       |
 1232|       |    // Read the "scene" property, which specifies which scene to load
 1233|       |    // and recursively load everything referenced by it
 1234|  2.48k|    Value *curScene = FindString(doc, "scene");
 1235|  2.48k|    if (nullptr != curScene) {
  ------------------
  |  Branch (1235:9): [True: 0, False: 2.48k]
  ------------------
 1236|      0|        this->scene = scenes.Get(curScene->GetString());
 1237|      0|    }
 1238|       |
 1239|       |    // Clean up
 1240|  4.97k|    for (size_t i = 0; i < mDicts.size(); ++i) {
  ------------------
  |  Branch (1240:24): [True: 2.49k, False: 2.48k]
  ------------------
 1241|  2.49k|        mDicts[i]->DetachFromDocument();
 1242|  2.49k|    }
 1243|  2.48k|}
_ZN4glTF5Asset8OpenFileERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEPKcb:
 1271|  4.58k|inline IOStream *Asset::OpenFile(const std::string &path, const char *mode, bool absolute) {
 1272|  4.58k|#ifdef ASSIMP_API
 1273|  4.58k|    (void)absolute;
 1274|  4.58k|    return mIOSystem->Open(path, mode);
 1275|       |#else
 1276|       |    if (path.size() < 2) return 0;
 1277|       |    if (!absolute && path[1] != ':' && path[0] != '/') { // relative?
 1278|       |        path = mCurrentAssetDir + path;
 1279|       |    }
 1280|       |    FILE *f = fopen(path.c_str(), mode);
 1281|       |    return f ? new IOStream(f) : 0;
 1282|       |#endif
 1283|  4.58k|}
_ZN4glTF5Asset11SetAsBinaryEv:
 1245|  2.44k|inline void Asset::SetAsBinary() {
 1246|  2.44k|    if (!extensionsUsed.KHR_binary_glTF) {
  ------------------
  |  Branch (1246:9): [True: 2.44k, False: 0]
  ------------------
 1247|  2.44k|        extensionsUsed.KHR_binary_glTF = true;
 1248|  2.44k|        mBodyBuffer = buffers.Create("binary_glTF");
 1249|  2.44k|        mBodyBuffer->MarkAsSpecial();
 1250|  2.44k|    }
 1251|  2.44k|}
_ZN4glTF8LazyDictINS_6BufferEE6CreateEPKc:
  149|  2.44k|Ref<T> LazyDict<T>::Create(const char *id) {
  150|  2.44k|    Asset::IdMap::iterator it = mAsset.mUsedIds.find(id);
  151|  2.44k|    if (it != mAsset.mUsedIds.end()) {
  ------------------
  |  Branch (151:9): [True: 0, False: 2.44k]
  ------------------
  152|      0|        throw DeadlyImportError("GLTF: two objects with the same ID exist");
  153|      0|    }
  154|  2.44k|    T *inst = new T();
  155|  2.44k|    inst->id = id;
  156|  2.44k|    return Add(inst);
  157|  2.44k|}
_ZN4glTF6BufferC2Ev:
  164|  2.44k|        byteLength(0), type(Type_arraybuffer), EncodedRegion_Current(nullptr), mIsSpecial(false) {}
_ZN4glTF8LazyDictINS_6BufferEE3AddEPS1_:
  140|  2.44k|Ref<T> LazyDict<T>::Add(T *obj) {
  141|  2.44k|    unsigned int idx = unsigned(mObjs.size());
  142|  2.44k|    mObjs.push_back(obj);
  143|  2.44k|    mObjsById[obj->id] = idx;
  144|  2.44k|    mAsset.mUsedIds[obj->id] = true;
  145|  2.44k|    return Ref<T>(mObjs, idx);
  146|  2.44k|}
_ZN4glTF5Asset16ReadBinaryHeaderERN6Assimp8IOStreamE:
 1123|  2.44k|inline void Asset::ReadBinaryHeader(IOStream &stream) {
 1124|  2.44k|    GLB_Header header;
 1125|  2.44k|    if (stream.Read(&header, sizeof(header), 1) != 1) {
  ------------------
  |  Branch (1125:9): [True: 0, False: 2.44k]
  ------------------
 1126|      0|        throw DeadlyImportError("GLTF: Unable to read the file header");
 1127|      0|    }
 1128|       |
 1129|  2.44k|    if (strncmp((char *)header.magic, AI_GLB_MAGIC_NUMBER, sizeof(header.magic)) != 0) {
  ------------------
  |  |  127|  2.44k|#define AI_GLB_MAGIC_NUMBER "glTF"
  ------------------
  |  Branch (1129:9): [True: 0, False: 2.44k]
  ------------------
 1130|      0|        throw DeadlyImportError("GLTF: Invalid binary glTF file");
 1131|      0|    }
 1132|       |
 1133|  2.44k|    AI_SWAP4(header.version);
 1134|  2.44k|    asset.version = ai_to_string(header.version);
 1135|  2.44k|    if (header.version != 1) {
  ------------------
  |  Branch (1135:9): [True: 2.28k, False: 160]
  ------------------
 1136|  2.28k|        throw DeadlyImportError("GLTF: Unsupported binary glTF version");
 1137|  2.28k|    }
 1138|       |
 1139|    160|    AI_SWAP4(header.sceneFormat);
 1140|    160|    if (header.sceneFormat != SceneFormat_JSON) {
  ------------------
  |  Branch (1140:9): [True: 2, False: 158]
  ------------------
 1141|      2|        throw DeadlyImportError("GLTF: Unsupported binary glTF scene format");
 1142|      2|    }
 1143|       |
 1144|    158|    AI_SWAP4(header.length);
 1145|    158|    AI_SWAP4(header.sceneLength);
 1146|       |
 1147|    158|    static_assert(std::numeric_limits<uint32_t>::max() <= std::numeric_limits<size_t>::max(), "size_t must be at least 32bits");
 1148|    158|    mSceneLength = static_cast<size_t>(header.sceneLength); // Can't be larger than 4GB (max. uint32_t)
 1149|       |
 1150|    158|    mBodyOffset = sizeof(header) + mSceneLength;
 1151|    158|    mBodyOffset = (mBodyOffset + 3) & ~3; // Round up to next multiple of 4
 1152|       |
 1153|    158|    mBodyLength = header.length - mBodyOffset;
 1154|    158|}
_ZN4glTF13AssetMetadata4ReadERN9rapidjson15GenericDocumentINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEES6_EE:
 1093|    744|inline void AssetMetadata::Read(Document &doc) {
 1094|       |    // read the version, etc.
 1095|    744|    if (Value *obj = FindObject(doc, "asset")) {
  ------------------
  |  Branch (1095:16): [True: 620, False: 124]
  ------------------
 1096|    620|        ReadMember(*obj, "copyright", copyright);
 1097|    620|        ReadMember(*obj, "generator", generator);
 1098|       |
 1099|    620|        premultipliedAlpha = MemberOrDefault(*obj, "premultipliedAlpha", false);
 1100|       |
 1101|    620|        if (Value *versionString = FindString(*obj, "version")) {
  ------------------
  |  Branch (1101:20): [True: 572, False: 48]
  ------------------
 1102|    572|            version = versionString->GetString();
 1103|    572|        } else if (Value *versionNumber = FindNumber(*obj, "version")) {
  ------------------
  |  Branch (1103:27): [True: 8, False: 40]
  ------------------
 1104|      8|            char buf[4];
 1105|       |
 1106|      8|            ai_snprintf(buf, 4, "%.1f", versionNumber->GetDouble());
 1107|       |
 1108|      8|            version = buf;
 1109|      8|        }
 1110|       |
 1111|    620|        Value *curProfile = FindObject(*obj, "profile");
 1112|    620|        if (nullptr != curProfile) {
  ------------------
  |  Branch (1112:13): [True: 0, False: 620]
  ------------------
 1113|      0|            ReadMember(*curProfile, "api", this->profile.api);
 1114|      0|            ReadMember(*curProfile, "version", this->profile.version);
 1115|      0|        }
 1116|    620|    }
 1117|    744|}
_ZN4glTF5Asset18ReadExtensionsUsedERN9rapidjson15GenericDocumentINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEES6_EE:
 1253|    196|inline void Asset::ReadExtensionsUsed(Document &doc) {
 1254|    196|    Value *extsUsed = FindArray(doc, "extensionsUsed");
 1255|    196|    if (!extsUsed) return;
  ------------------
  |  Branch (1255:9): [True: 192, False: 4]
  ------------------
 1256|       |
 1257|      4|    std::gltf_unordered_map<std::string, bool> exts;
 1258|       |
 1259|      4|    for (unsigned int i = 0; i < extsUsed->Size(); ++i) {
  ------------------
  |  Branch (1259:30): [True: 0, False: 4]
  ------------------
 1260|      0|        if ((*extsUsed)[i].IsString()) {
  ------------------
  |  Branch (1260:13): [True: 0, False: 0]
  ------------------
 1261|      0|            exts[(*extsUsed)[i].GetString()] = true;
 1262|      0|        }
 1263|      0|    }
 1264|       |
 1265|      4|    CHECK_EXT(KHR_binary_glTF);
  ------------------
  |  |  237|      4|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 4]
  |  |  ------------------
  ------------------
 1266|      4|    CHECK_EXT(KHR_materials_common);
  ------------------
  |  |  237|      4|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 4]
  |  |  ------------------
  ------------------
 1267|       |
 1268|      4|#undef CHECK_EXT
 1269|      4|}

_ZN6Assimp12glTFImporterC2Ev:
  148|  3.48k|        mScene(nullptr) {
  149|       |    // empty
  150|  3.48k|}
_ZNK6Assimp12glTFImporter7GetInfoEv:
  152|  10.5k|const aiImporterDesc *glTFImporter::GetInfo() const {
  153|  10.5k|    return &desc;
  154|  10.5k|}
_ZNK6Assimp12glTFImporter7CanReadERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEPNS_8IOSystemEb:
  156|  4.49k|bool glTFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /* checkSig */) const {
  157|  4.49k|    Asset asset(pIOHandler);
  158|  4.49k|    try {
  159|  4.49k|        asset.Load(pFile,
  160|  4.49k|                   CheckMagicToken(
  161|  4.49k|                       pIOHandler, pFile, AI_GLB_MAGIC_NUMBER, 1, 0,
  ------------------
  |  |  127|  4.49k|#define AI_GLB_MAGIC_NUMBER "glTF"
  ------------------
  162|  4.49k|                       static_cast<unsigned int>(strlen(AI_GLB_MAGIC_NUMBER))));
  ------------------
  |  |  127|  4.49k|#define AI_GLB_MAGIC_NUMBER "glTF"
  ------------------
  163|  4.49k|        return asset.asset;
  164|  4.49k|    } catch (...) {
  165|  3.86k|        return false;
  166|  3.86k|    }
  167|  4.49k|}
_ZNK6Assimp12glTFImporter15ImportMaterialsERN4glTF5AssetE:
  169|     89|void glTFImporter::ImportMaterials(Asset &r) const {
  170|     89|    mScene->mNumMaterials = r.materials.Size();
  171|     89|    if (mScene->mNumMaterials == 0) {
  ------------------
  |  Branch (171:9): [True: 89, False: 0]
  ------------------
  172|     89|        createDefaultMaterial(mScene);
  173|     89|        return;
  174|     89|    }
  175|       |
  176|      0|    mScene->mMaterials = new aiMaterial *[mScene->mNumMaterials];
  177|      0|    for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
  ------------------
  |  Branch (177:30): [True: 0, False: 0]
  ------------------
  178|      0|        aiMaterial *aimat = mScene->mMaterials[i] = new aiMaterial();
  179|       |
  180|      0|        Material &mat = r.materials[i];
  181|      0|        aiString str(mat.id);
  182|      0|        aimat->AddProperty(&str, AI_MATKEY_NAME);
  183|       |
  184|      0|        SetMaterialColorProperty(embeddedTexIdxs, r, mat.ambient, aimat, aiTextureType_AMBIENT, AI_MATKEY_COLOR_AMBIENT);
  185|      0|        SetMaterialColorProperty(embeddedTexIdxs, r, mat.diffuse, aimat, aiTextureType_DIFFUSE, AI_MATKEY_COLOR_DIFFUSE);
  186|      0|        SetMaterialColorProperty(embeddedTexIdxs, r, mat.specular, aimat, aiTextureType_SPECULAR, AI_MATKEY_COLOR_SPECULAR);
  187|      0|        SetMaterialColorProperty(embeddedTexIdxs, r, mat.emission, aimat, aiTextureType_EMISSIVE, AI_MATKEY_COLOR_EMISSIVE);
  188|       |
  189|      0|        aimat->AddProperty(&mat.doubleSided, 1, AI_MATKEY_TWOSIDED);
  190|       |
  191|      0|        if (mat.transparent && (mat.transparency != 1.0f)) {
  ------------------
  |  Branch (191:13): [True: 0, False: 0]
  |  Branch (191:32): [True: 0, False: 0]
  ------------------
  192|      0|            aimat->AddProperty(&mat.transparency, 1, AI_MATKEY_OPACITY);
  193|      0|        }
  194|       |
  195|      0|        if (mat.shininess > 0.f) {
  ------------------
  |  Branch (195:13): [True: 0, False: 0]
  ------------------
  196|       |            aimat->AddProperty(&mat.shininess, 1, AI_MATKEY_SHININESS);
  197|      0|        }
  198|      0|    }
  199|      0|}
_ZN6Assimp12glTFImporter12ImportMeshesERN4glTF5AssetE:
  201|     89|void glTFImporter::ImportMeshes(Asset &r) {
  202|     89|    std::vector<aiMesh *> meshes;
  203|       |
  204|     89|    unsigned int k = 0;
  205|     89|    meshOffsets.clear();
  206|       |
  207|     89|    for (unsigned int m = 0; m < r.meshes.Size(); ++m) {
  ------------------
  |  Branch (207:30): [True: 0, False: 89]
  ------------------
  208|      0|        Mesh &mesh = r.meshes[m];
  209|       |
  210|       |        // Check if mesh extensions is used
  211|      0|        if (mesh.Extension.size() > 0) {
  ------------------
  |  Branch (211:13): [True: 0, False: 0]
  ------------------
  212|      0|#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
  213|      0|            for (Mesh::SExtension *cur_ext : mesh.Extension) {
  ------------------
  |  Branch (213:44): [True: 0, False: 0]
  ------------------
  214|      0|                if (cur_ext->Type == Mesh::SExtension::EType::Compression_Open3DGC) {
  ------------------
  |  Branch (214:21): [True: 0, False: 0]
  ------------------
  215|       |                    // Limitations for meshes when using Open3DGC-compression.
  216|       |                    // It's a current limitation of sp... Specification have not this part still - about mesh compression. Why only one primitive?
  217|       |                    // Because glTF is very flexibly. But in fact it ugly flexible. Every primitive can has own set of accessors and accessors can
  218|       |                    // point to a-a-a-a-any part of buffer (through bufferview of course) and even to another buffer. We know that "Open3DGC-compression"
  219|       |                    // is applicable only to part of buffer. As we can't guaranty continuity of the data for decoder, we will limit quantity of primitives.
  220|       |                    // Yes indices, coordinates etc. still can br stored in different buffers, but with current specification it's a exporter problem.
  221|       |                    // Also primitive can has only one of "POSITION", "NORMAL" and less then "AI_MAX_NUMBER_OF_TEXTURECOORDS" of "TEXCOORD". All accessor
  222|       |                    // of primitive must point to one continuous region of the buffer.
  223|      0|                    if (mesh.primitives.size() > 2) throw DeadlyImportError("GLTF: When using Open3DGC compression then only one primitive per mesh are allowed.");
  ------------------
  |  Branch (223:25): [True: 0, False: 0]
  ------------------
  224|       |
  225|      0|                    Mesh::SCompression_Open3DGC *o3dgc_ext = (Mesh::SCompression_Open3DGC *)cur_ext;
  226|      0|                    Ref<Buffer> buf = r.buffers.Get(o3dgc_ext->Buffer);
  227|       |
  228|      0|                    buf->EncodedRegion_SetCurrent(mesh.id);
  229|      0|                } else
  230|      0|                {
  231|      0|                    throw DeadlyImportError("GLTF: Can not import mesh: unknown mesh extension (code: \"", ai_to_string(cur_ext->Type),
  232|      0|                                            "\"), only Open3DGC is supported.");
  233|      0|                }
  234|      0|            }
  235|      0|#endif
  236|      0|        } // if(mesh.Extension.size() > 0)
  237|       |
  238|      0|        meshOffsets.push_back(k);
  239|      0|        k += static_cast<unsigned>(mesh.primitives.size());
  240|       |
  241|      0|        for (unsigned int p = 0; p < mesh.primitives.size(); ++p) {
  ------------------
  |  Branch (241:34): [True: 0, False: 0]
  ------------------
  242|      0|            auto &[mode, attributes, indices, material] = mesh.primitives[p];
  243|       |
  244|      0|            aiMesh *aim = new aiMesh();
  245|      0|            meshes.push_back(aim);
  246|       |
  247|      0|            aim->mName = mesh.id;
  248|      0|            if (mesh.primitives.size() > 1) {
  ------------------
  |  Branch (248:17): [True: 0, False: 0]
  ------------------
  249|      0|                ai_uint32 &len = aim->mName.length;
  250|      0|                aim->mName.data[len] = '-';
  251|      0|                len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(AI_MAXLEN - len - 1), p);
  252|      0|            }
  253|       |
  254|      0|            switch (mode) {
  ------------------
  |  Branch (254:21): [True: 0, False: 0]
  ------------------
  255|      0|            case PrimitiveMode_POINTS:
  ------------------
  |  Branch (255:13): [True: 0, False: 0]
  ------------------
  256|      0|                aim->mPrimitiveTypes |= aiPrimitiveType_POINT;
  257|      0|                break;
  258|       |
  259|      0|            case PrimitiveMode_LINES:
  ------------------
  |  Branch (259:13): [True: 0, False: 0]
  ------------------
  260|      0|            case PrimitiveMode_LINE_LOOP:
  ------------------
  |  Branch (260:13): [True: 0, False: 0]
  ------------------
  261|      0|            case PrimitiveMode_LINE_STRIP:
  ------------------
  |  Branch (261:13): [True: 0, False: 0]
  ------------------
  262|      0|                aim->mPrimitiveTypes |= aiPrimitiveType_LINE;
  263|      0|                break;
  264|       |
  265|      0|            case PrimitiveMode_TRIANGLES:
  ------------------
  |  Branch (265:13): [True: 0, False: 0]
  ------------------
  266|      0|            case PrimitiveMode_TRIANGLE_STRIP:
  ------------------
  |  Branch (266:13): [True: 0, False: 0]
  ------------------
  267|      0|            case PrimitiveMode_TRIANGLE_FAN:
  ------------------
  |  Branch (267:13): [True: 0, False: 0]
  ------------------
  268|      0|                aim->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
  269|      0|                break;
  270|      0|            }
  271|       |
  272|      0|            Mesh::Primitive::Attributes &attr = attributes;
  273|       |
  274|      0|            if (attr.position.size() > 0 && attr.position[0]) {
  ------------------
  |  Branch (274:17): [True: 0, False: 0]
  |  Branch (274:45): [True: 0, False: 0]
  ------------------
  275|      0|                aim->mNumVertices = attr.position[0]->count;
  276|      0|                attr.position[0]->ExtractData(aim->mVertices);
  277|      0|            }
  278|       |
  279|      0|            if (attr.normal.size() > 0 && attr.normal[0]) attr.normal[0]->ExtractData(aim->mNormals);
  ------------------
  |  Branch (279:17): [True: 0, False: 0]
  |  Branch (279:43): [True: 0, False: 0]
  ------------------
  280|       |
  281|      0|            for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
  ------------------
  |  Branch (281:33): [True: 0, False: 0]
  |  Branch (281:62): [True: 0, False: 0]
  ------------------
  282|      0|                attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);
  283|      0|                aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();
  284|       |
  285|      0|                aiVector3D *values = aim->mTextureCoords[tc];
  286|      0|                for (unsigned int i = 0; i < aim->mNumVertices; ++i) {
  ------------------
  |  Branch (286:42): [True: 0, False: 0]
  ------------------
  287|      0|                    values[i].y = 1 - values[i].y; // Flip Y coords
  288|      0|                }
  289|      0|            }
  290|       |
  291|      0|            aiFace *faces = nullptr;
  292|      0|            unsigned int nFaces = 0;
  293|       |
  294|      0|            if (indices) {
  ------------------
  |  Branch (294:17): [True: 0, False: 0]
  ------------------
  295|      0|                unsigned int count = indices->count;
  296|       |
  297|      0|                Accessor::Indexer data = indices->GetIndexer();
  298|      0|                ai_assert(data.IsValid());
  299|       |
  300|      0|                switch (mode) {
  ------------------
  |  Branch (300:25): [True: 0, False: 0]
  ------------------
  301|      0|                case PrimitiveMode_POINTS: {
  ------------------
  |  Branch (301:17): [True: 0, False: 0]
  ------------------
  302|      0|                    nFaces = count;
  303|      0|                    faces = new aiFace[nFaces];
  304|      0|                    for (unsigned int i = 0; i < count; ++i) {
  ------------------
  |  Branch (304:46): [True: 0, False: 0]
  ------------------
  305|      0|                        SetFace(faces[i], data.GetUInt(i));
  306|      0|                    }
  307|      0|                    break;
  308|      0|                }
  309|       |
  310|      0|                case PrimitiveMode_LINES: {
  ------------------
  |  Branch (310:17): [True: 0, False: 0]
  ------------------
  311|      0|                    nFaces = count / 2;
  312|      0|                    if (nFaces * 2 != count) {
  ------------------
  |  Branch (312:25): [True: 0, False: 0]
  ------------------
  313|      0|                        ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped.");
  314|      0|                        count = nFaces * 2;
  315|      0|                    }
  316|      0|                    faces = new aiFace[nFaces];
  317|      0|                    for (unsigned int i = 0; i < count; i += 2) {
  ------------------
  |  Branch (317:46): [True: 0, False: 0]
  ------------------
  318|      0|                        SetFace(faces[i / 2], data.GetUInt(i), data.GetUInt(i + 1));
  319|      0|                    }
  320|      0|                    break;
  321|      0|                }
  322|       |
  323|      0|                case PrimitiveMode_LINE_LOOP:
  ------------------
  |  Branch (323:17): [True: 0, False: 0]
  ------------------
  324|      0|                case PrimitiveMode_LINE_STRIP: {
  ------------------
  |  Branch (324:17): [True: 0, False: 0]
  ------------------
  325|      0|                    nFaces = count - ((mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
  ------------------
  |  Branch (325:39): [True: 0, False: 0]
  ------------------
  326|      0|                    faces = new aiFace[nFaces];
  327|      0|                    SetFace(faces[0], data.GetUInt(0), data.GetUInt(1));
  328|      0|                    for (unsigned int i = 2; i < count; ++i) {
  ------------------
  |  Branch (328:46): [True: 0, False: 0]
  ------------------
  329|      0|                        SetFace(faces[i - 1], faces[i - 2].mIndices[1], data.GetUInt(i));
  330|      0|                    }
  331|      0|                    if (mode == PrimitiveMode_LINE_LOOP) { // close the loop
  ------------------
  |  Branch (331:25): [True: 0, False: 0]
  ------------------
  332|      0|                        SetFace(faces[count - 1], faces[count - 2].mIndices[1], faces[0].mIndices[0]);
  333|      0|                    }
  334|      0|                    break;
  335|      0|                }
  336|       |
  337|      0|                case PrimitiveMode_TRIANGLES: {
  ------------------
  |  Branch (337:17): [True: 0, False: 0]
  ------------------
  338|      0|                    nFaces = count / 3;
  339|      0|                    if (nFaces * 3 != count) {
  ------------------
  |  Branch (339:25): [True: 0, False: 0]
  ------------------
  340|      0|                        ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped.");
  341|      0|                        count = nFaces * 3;
  342|      0|                    }
  343|      0|                    faces = new aiFace[nFaces];
  344|      0|                    for (unsigned int i = 0; i < count; i += 3) {
  ------------------
  |  Branch (344:46): [True: 0, False: 0]
  ------------------
  345|      0|                        SetFace(faces[i / 3], data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
  346|      0|                    }
  347|      0|                    break;
  348|      0|                }
  349|      0|                case PrimitiveMode_TRIANGLE_STRIP: {
  ------------------
  |  Branch (349:17): [True: 0, False: 0]
  ------------------
  350|      0|                    nFaces = count - 2;
  351|      0|                    faces = new aiFace[nFaces];
  352|      0|                    SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
  353|      0|                    for (unsigned int i = 3; i < count; ++i) {
  ------------------
  |  Branch (353:46): [True: 0, False: 0]
  ------------------
  354|      0|                        SetFace(faces[i - 2], faces[i - 1].mIndices[1], faces[i - 1].mIndices[2], data.GetUInt(i));
  355|      0|                    }
  356|      0|                    break;
  357|      0|                }
  358|      0|                case PrimitiveMode_TRIANGLE_FAN:
  ------------------
  |  Branch (358:17): [True: 0, False: 0]
  ------------------
  359|      0|                    nFaces = count - 2;
  360|      0|                    faces = new aiFace[nFaces];
  361|      0|                    SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
  362|      0|                    for (unsigned int i = 3; i < count; ++i) {
  ------------------
  |  Branch (362:46): [True: 0, False: 0]
  ------------------
  363|      0|                        SetFace(faces[i - 2], faces[0].mIndices[0], faces[i - 1].mIndices[2], data.GetUInt(i));
  364|      0|                    }
  365|      0|                    break;
  366|      0|                }
  367|      0|            } else { // no indices provided so directly generate from counts
  368|       |
  369|       |                // use the already determined count as it includes checks
  370|      0|                unsigned int count = aim->mNumVertices;
  371|       |
  372|      0|                switch (mode) {
  ------------------
  |  Branch (372:25): [True: 0, False: 0]
  ------------------
  373|      0|                case PrimitiveMode_POINTS: {
  ------------------
  |  Branch (373:17): [True: 0, False: 0]
  ------------------
  374|      0|                    nFaces = count;
  375|      0|                    faces = new aiFace[nFaces];
  376|      0|                    for (unsigned int i = 0; i < count; ++i) {
  ------------------
  |  Branch (376:46): [True: 0, False: 0]
  ------------------
  377|      0|                        SetFace(faces[i], i);
  378|      0|                    }
  379|      0|                    break;
  380|      0|                }
  381|       |
  382|      0|                case PrimitiveMode_LINES: {
  ------------------
  |  Branch (382:17): [True: 0, False: 0]
  ------------------
  383|      0|                    nFaces = count / 2;
  384|      0|                    if (nFaces * 2 != count) {
  ------------------
  |  Branch (384:25): [True: 0, False: 0]
  ------------------
  385|      0|                        ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped.");
  386|      0|                        count = nFaces * 2;
  387|      0|                    }
  388|      0|                    faces = new aiFace[nFaces];
  389|      0|                    for (unsigned int i = 0; i < count; i += 2) {
  ------------------
  |  Branch (389:46): [True: 0, False: 0]
  ------------------
  390|      0|                        SetFace(faces[i / 2], i, i + 1);
  391|      0|                    }
  392|      0|                    break;
  393|      0|                }
  394|       |
  395|      0|                case PrimitiveMode_LINE_LOOP:
  ------------------
  |  Branch (395:17): [True: 0, False: 0]
  ------------------
  396|      0|                case PrimitiveMode_LINE_STRIP: {
  ------------------
  |  Branch (396:17): [True: 0, False: 0]
  ------------------
  397|      0|                    nFaces = count - ((mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
  ------------------
  |  Branch (397:39): [True: 0, False: 0]
  ------------------
  398|      0|                    faces = new aiFace[nFaces];
  399|      0|                    SetFace(faces[0], 0, 1);
  400|      0|                    for (unsigned int i = 2; i < count; ++i) {
  ------------------
  |  Branch (400:46): [True: 0, False: 0]
  ------------------
  401|      0|                        SetFace(faces[i - 1], faces[i - 2].mIndices[1], i);
  402|      0|                    }
  403|      0|                    if (mode == PrimitiveMode_LINE_LOOP) { // close the loop
  ------------------
  |  Branch (403:25): [True: 0, False: 0]
  ------------------
  404|      0|                        SetFace(faces[count - 1], faces[count - 2].mIndices[1], faces[0].mIndices[0]);
  405|      0|                    }
  406|      0|                    break;
  407|      0|                }
  408|       |
  409|      0|                case PrimitiveMode_TRIANGLES: {
  ------------------
  |  Branch (409:17): [True: 0, False: 0]
  ------------------
  410|      0|                    nFaces = count / 3;
  411|      0|                    if (nFaces * 3 != count) {
  ------------------
  |  Branch (411:25): [True: 0, False: 0]
  ------------------
  412|      0|                        ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped.");
  413|      0|                        count = nFaces * 3;
  414|      0|                    }
  415|      0|                    faces = new aiFace[nFaces];
  416|      0|                    for (unsigned int i = 0; i < count; i += 3) {
  ------------------
  |  Branch (416:46): [True: 0, False: 0]
  ------------------
  417|      0|                        SetFace(faces[i / 3], i, i + 1, i + 2);
  418|      0|                    }
  419|      0|                    break;
  420|      0|                }
  421|      0|                case PrimitiveMode_TRIANGLE_STRIP: {
  ------------------
  |  Branch (421:17): [True: 0, False: 0]
  ------------------
  422|      0|                    nFaces = count - 2;
  423|      0|                    faces = new aiFace[nFaces];
  424|      0|                    SetFace(faces[0], 0, 1, 2);
  425|      0|                    for (unsigned int i = 3; i < count; ++i) {
  ------------------
  |  Branch (425:46): [True: 0, False: 0]
  ------------------
  426|      0|                        SetFace(faces[i - 2], faces[i - 1].mIndices[1], faces[i - 1].mIndices[2], i);
  427|      0|                    }
  428|      0|                    break;
  429|      0|                }
  430|      0|                case PrimitiveMode_TRIANGLE_FAN:
  ------------------
  |  Branch (430:17): [True: 0, False: 0]
  ------------------
  431|      0|                    nFaces = count - 2;
  432|      0|                    faces = new aiFace[nFaces];
  433|      0|                    SetFace(faces[0], 0, 1, 2);
  434|      0|                    for (unsigned int i = 3; i < count; ++i) {
  ------------------
  |  Branch (434:46): [True: 0, False: 0]
  ------------------
  435|      0|                        SetFace(faces[i - 2], faces[0].mIndices[0], faces[i - 1].mIndices[2], i);
  436|      0|                    }
  437|      0|                    break;
  438|      0|                }
  439|      0|            }
  440|       |
  441|      0|            if (faces) {
  ------------------
  |  Branch (441:17): [True: 0, False: 0]
  ------------------
  442|      0|                aim->mFaces = faces;
  443|      0|                aim->mNumFaces = nFaces;
  444|      0|                const bool validRes = CheckValidFacesIndices(faces, nFaces, aim->mNumVertices);
  445|      0|                if (!validRes) {
  ------------------
  |  Branch (445:21): [True: 0, False: 0]
  ------------------
  446|      0|                    ai_assert(validRes);
  447|      0|                    ASSIMP_LOG_WARN("Invalid number of faces detected.");
  448|      0|                }
  449|      0|            }
  450|       |
  451|      0|            if (material) {
  ------------------
  |  Branch (451:17): [True: 0, False: 0]
  ------------------
  452|      0|                aim->mMaterialIndex = material.GetIndex();
  453|      0|            }
  454|      0|        }
  455|      0|    }
  456|       |
  457|     89|    meshOffsets.push_back(k);
  458|       |
  459|     89|    CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes);
  460|     89|}
_ZNK6Assimp12glTFImporter13ImportCamerasERN4glTF5AssetE:
  462|     89|void glTFImporter::ImportCameras(Asset &r) const {
  463|     89|    if (!r.cameras.Size()) {
  ------------------
  |  Branch (463:9): [True: 89, False: 0]
  ------------------
  464|     89|        return;
  465|     89|    }
  466|       |
  467|      0|    mScene->mNumCameras = r.cameras.Size();
  468|      0|    mScene->mCameras = new aiCamera *[r.cameras.Size()];
  469|      0|    for (size_t i = 0; i < r.cameras.Size(); ++i) {
  ------------------
  |  Branch (469:24): [True: 0, False: 0]
  ------------------
  470|      0|        const Camera &cam = r.cameras[i];
  471|      0|        mScene->mCameras[i] = new aiCamera();
  472|      0|        const auto aiCameraPtr = mScene->mCameras[i];
  473|      0|        if (cam.type == Camera::Perspective) {
  ------------------
  |  Branch (473:13): [True: 0, False: 0]
  ------------------
  474|      0|            aiCameraPtr->mAspect = cam.perspective.aspectRatio;
  475|      0|            aiCameraPtr->mHorizontalFOV = cam.perspective.yfov * ((aiCameraPtr->mAspect == 0.f) ? 1.f : aiCameraPtr->mAspect);
  ------------------
  |  Branch (475:67): [True: 0, False: 0]
  ------------------
  476|      0|            aiCameraPtr->mClipPlaneFar = cam.perspective.zfar;
  477|      0|            aiCameraPtr->mClipPlaneNear = cam.perspective.znear;
  478|      0|        } else {
  479|      0|            aiCameraPtr->mClipPlaneFar = cam.ortographic.zfar;
  480|      0|            aiCameraPtr->mClipPlaneNear = cam.ortographic.znear;
  481|      0|            aiCameraPtr->mHorizontalFOV = 0.0;
  482|      0|            aiCameraPtr->mAspect = 1.0f;
  483|      0|            if (0.f != cam.ortographic.ymag) {
  ------------------
  |  Branch (483:17): [True: 0, False: 0]
  ------------------
  484|      0|                aiCameraPtr->mAspect = cam.ortographic.xmag / cam.ortographic.ymag;
  485|      0|            }
  486|      0|        }
  487|      0|    }
  488|      0|}
_ZNK6Assimp12glTFImporter12ImportLightsERN4glTF5AssetE:
  490|     89|void glTFImporter::ImportLights(Asset &r) const {
  491|     89|    if (!r.lights.Size()) {
  ------------------
  |  Branch (491:9): [True: 89, False: 0]
  ------------------
  492|     89|        return;
  493|     89|    }
  494|       |
  495|      0|    mScene->mNumLights = r.lights.Size();
  496|      0|    mScene->mLights = new aiLight *[r.lights.Size()];
  497|       |
  498|      0|    for (size_t i = 0; i < r.lights.Size(); ++i) {
  ------------------
  |  Branch (498:24): [True: 0, False: 0]
  ------------------
  499|      0|        Light &l = r.lights[i];
  500|       |
  501|      0|        aiLight *ail = mScene->mLights[i] = new aiLight();
  502|       |
  503|      0|        switch (l.type) {
  504|      0|        case Light::Type_directional:
  ------------------
  |  Branch (504:9): [True: 0, False: 0]
  ------------------
  505|      0|            ail->mType = aiLightSource_DIRECTIONAL;
  506|      0|            break;
  507|       |
  508|      0|        case Light::Type_spot:
  ------------------
  |  Branch (508:9): [True: 0, False: 0]
  ------------------
  509|      0|            ail->mType = aiLightSource_SPOT;
  510|      0|            break;
  511|       |
  512|      0|        case Light::Type_ambient:
  ------------------
  |  Branch (512:9): [True: 0, False: 0]
  ------------------
  513|      0|            ail->mType = aiLightSource_AMBIENT;
  514|      0|            break;
  515|       |
  516|      0|        default: // Light::Type_point
  ------------------
  |  Branch (516:9): [True: 0, False: 0]
  ------------------
  517|      0|            ail->mType = aiLightSource_POINT;
  518|      0|            break;
  519|      0|        }
  520|       |
  521|      0|        CopyValue(l.color, ail->mColorAmbient);
  522|      0|        CopyValue(l.color, ail->mColorDiffuse);
  523|      0|        CopyValue(l.color, ail->mColorSpecular);
  524|       |
  525|      0|        ail->mAngleOuterCone = l.falloffAngle;
  526|      0|        ail->mAngleInnerCone = l.falloffAngle * (1.0f - 1.0f / (1.0f + l.falloffExponent)); 
  527|       |
  528|      0|        ail->mAttenuationConstant = l.constantAttenuation;
  529|      0|        ail->mAttenuationLinear = l.linearAttenuation;
  530|      0|        ail->mAttenuationQuadratic = l.quadraticAttenuation;
  531|      0|    }
  532|      0|}
_ZN6Assimp12glTFImporter11ImportNodesERN4glTF5AssetE:
  607|     89|void glTFImporter::ImportNodes(Asset &r) {
  608|     89|    if (!r.scene) {
  ------------------
  |  Branch (608:9): [True: 89, False: 0]
  ------------------
  609|     89|        return;
  610|     89|    }
  611|       |
  612|      0|    std::vector<Ref<Node>> rootNodes = r.scene->nodes;
  613|       |
  614|       |    // The root nodes
  615|      0|    if (auto numRootNodes = static_cast<unsigned>(rootNodes.size()); numRootNodes == 1) { // a single root node: use it
  ------------------
  |  Branch (615:70): [True: 0, False: 0]
  ------------------
  616|      0|        mScene->mRootNode = ImportNode(mScene, r, meshOffsets, rootNodes[0]);
  617|      0|    } else if (numRootNodes > 1) { // more than one root node: create a fake root
  ------------------
  |  Branch (617:16): [True: 0, False: 0]
  ------------------
  618|      0|        aiNode *root = new aiNode("ROOT");
  619|      0|        root->mChildren = new aiNode *[numRootNodes];
  620|      0|        for (unsigned int i = 0; i < numRootNodes; ++i) {
  ------------------
  |  Branch (620:34): [True: 0, False: 0]
  ------------------
  621|      0|            aiNode *node = ImportNode(mScene, r, meshOffsets, rootNodes[i]);
  622|      0|            node->mParent = root;
  623|      0|            root->mChildren[root->mNumChildren++] = node;
  624|      0|        }
  625|      0|        mScene->mRootNode = root;
  626|      0|    }
  627|      0|}
_ZN6Assimp12glTFImporter22ImportEmbeddedTexturesERN4glTF5AssetE:
  629|     89|void glTFImporter::ImportEmbeddedTextures(Asset &r) {
  630|     89|    embeddedTexIdxs.resize(r.images.Size(), -1);
  631|       |
  632|     89|    int numEmbeddedTexs = 0;
  633|     89|    for (size_t i = 0; i < r.images.Size(); ++i) {
  ------------------
  |  Branch (633:24): [True: 0, False: 89]
  ------------------
  634|      0|        if (r.images[i].HasData())
  ------------------
  |  Branch (634:13): [True: 0, False: 0]
  ------------------
  635|      0|            numEmbeddedTexs += 1;
  636|      0|    }
  637|       |
  638|     89|    if (numEmbeddedTexs == 0) {
  ------------------
  |  Branch (638:9): [True: 89, False: 0]
  ------------------
  639|     89|        return;
  640|     89|    }
  641|       |
  642|      0|    mScene->mTextures = new aiTexture *[numEmbeddedTexs];
  643|       |
  644|       |    // Add the embedded textures
  645|      0|    for (size_t i = 0; i < r.images.Size(); ++i) {
  ------------------
  |  Branch (645:24): [True: 0, False: 0]
  ------------------
  646|      0|        Image &img = r.images[i];
  647|      0|        if (!img.HasData()) continue;
  ------------------
  |  Branch (647:13): [True: 0, False: 0]
  ------------------
  648|       |
  649|      0|        int idx = mScene->mNumTextures++;
  650|      0|        embeddedTexIdxs[i] = idx;
  651|       |
  652|      0|        aiTexture *tex = mScene->mTextures[idx] = new aiTexture();
  653|       |
  654|      0|        const size_t length = img.GetDataLength();
  655|      0|        void *data = img.StealData();
  656|       |
  657|      0|        tex->mFilename = img.name;
  658|      0|        tex->mWidth = static_cast<unsigned int>(length);
  659|      0|        tex->mHeight = 0;
  660|      0|        tex->pcData = static_cast<aiTexel *>(data);
  661|       |
  662|      0|        if (!img.mimeType.empty()) {
  ------------------
  |  Branch (662:13): [True: 0, False: 0]
  ------------------
  663|      0|            if (const char *ext = strchr(img.mimeType.c_str(), '/') + 1) {
  ------------------
  |  Branch (663:29): [True: 0, False: 0]
  ------------------
  664|      0|                if (strncmp(ext, "jpeg", 4) == 0) {
  ------------------
  |  Branch (664:21): [True: 0, False: 0]
  ------------------
  665|      0|                    ext = "jpg";
  666|      0|                }
  667|       |
  668|      0|                tex->achFormatHint[3] = '\0';
  669|      0|                size_t len = strlen(ext);
  670|      0|                if (len > 3) len = 3;
  ------------------
  |  Branch (670:21): [True: 0, False: 0]
  ------------------
  671|      0|                memcpy(tex->achFormatHint, ext, len);
  672|      0|            }
  673|      0|        }
  674|      0|    }
  675|      0|}
_ZNK6Assimp12glTFImporter20ImportCommonMetadataERKN4glTF5AssetE:
  677|     89|void glTFImporter::ImportCommonMetadata(const Asset &a) const {
  678|     89|    ai_assert(mScene->mMetaData == nullptr);
  679|       |
  680|     89|    const bool hasVersion = !a.asset.version.empty();
  681|     89|    const bool hasGenerator = !a.asset.generator.empty();
  682|     89|    const bool hasCopyright = !a.asset.copyright.empty();
  683|     89|    if (hasVersion || hasGenerator || hasCopyright) {
  ------------------
  |  Branch (683:9): [True: 89, False: 0]
  |  Branch (683:23): [True: 0, False: 0]
  |  Branch (683:39): [True: 0, False: 0]
  ------------------
  684|     89|        mScene->mMetaData = new aiMetadata;
  685|     89|        if (hasVersion) {
  ------------------
  |  Branch (685:13): [True: 89, False: 0]
  ------------------
  686|     89|            mScene->mMetaData->Add(AI_METADATA_SOURCE_FORMAT_VERSION, aiString(a.asset.version));
  687|     89|        }
  688|     89|        if (hasGenerator) {
  ------------------
  |  Branch (688:13): [True: 20, False: 69]
  ------------------
  689|     20|            mScene->mMetaData->Add(AI_METADATA_SOURCE_GENERATOR, aiString(a.asset.generator));
  690|     20|        }
  691|     89|        if (hasCopyright) {
  ------------------
  |  Branch (691:13): [True: 12, False: 77]
  ------------------
  692|       |            mScene->mMetaData->Add(AI_METADATA_SOURCE_COPYRIGHT, aiString(a.asset.copyright));
  693|     12|        }
  694|     89|    }
  695|     89|}
_ZN6Assimp12glTFImporter14InternReadFileERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP7aiScenePNS_8IOSystemE:
  697|     89|void glTFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
  698|       |    // clean all member arrays
  699|     89|    meshOffsets.clear();
  700|     89|    embeddedTexIdxs.clear();
  701|       |
  702|     89|    this->mScene = pScene;
  703|       |
  704|       |    // read the asset file
  705|     89|    Asset asset(pIOHandler);
  706|     89|    asset.Load(pFile,
  707|     89|               CheckMagicToken(
  708|     89|                   pIOHandler, pFile, AI_GLB_MAGIC_NUMBER, 1, 0,
  ------------------
  |  |  127|     89|#define AI_GLB_MAGIC_NUMBER "glTF"
  ------------------
  709|     89|                   static_cast<unsigned int>(strlen(AI_GLB_MAGIC_NUMBER))));
  ------------------
  |  |  127|     89|#define AI_GLB_MAGIC_NUMBER "glTF"
  ------------------
  710|       |
  711|       |    //
  712|       |    // Copy the data out
  713|       |    //
  714|       |
  715|     89|    ImportEmbeddedTextures(asset);
  716|     89|    ImportMaterials(asset);
  717|       |
  718|     89|    ImportMeshes(asset);
  719|       |
  720|     89|    ImportCameras(asset);
  721|     89|    ImportLights(asset);
  722|       |
  723|     89|    ImportNodes(asset);
  724|     89|    ImportCommonMetadata(asset);
  725|       |
  726|     89|    if (pScene->mNumMeshes == 0) {
  ------------------
  |  Branch (726:9): [True: 89, False: 0]
  ------------------
  727|       |        pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
  728|     89|    }
  729|     89|}
glTFImporter.cpp:_ZN12_GLOBAL__N_121createDefaultMaterialEP7aiScene:
  135|     89|    void createDefaultMaterial(aiScene *scene) {
  136|     89|        if (scene == nullptr) {
  ------------------
  |  Branch (136:13): [True: 0, False: 89]
  ------------------
  137|      0|            return;
  138|      0|        }
  139|     89|        scene->mNumMaterials = 1;
  140|     89|        scene->mMaterials = nullptr;
  141|     89|        scene->mMaterials = new aiMaterial *[1];
  142|     89|        scene->mMaterials[0] = new aiMaterial();
  143|     89|    }

_ZN6Assimp12glTFImporterD2Ev:
   64|  3.48k|    ~glTFImporter() override = default;

_ZN5glTF26ObjectD2Ev:
  394|  38.0k|    virtual ~Object() = default;
_ZN5glTF215CustomExtensionD2Ev:
  367|   101k|    ~CustomExtension() = default;
_ZN5glTF210AttribType10FromStringEPKc:
  308|  6.80k|    inline static Value FromString(const char *str) {
  309|  22.4k|        for (size_t i = 0; i < NUM_VALUES; ++i) {
  ------------------
  |  Branch (309:28): [True: 22.1k, False: 368]
  ------------------
  310|  22.1k|            if (strcmp(data<0>::infos[i].name, str) == 0) {
  ------------------
  |  Branch (310:17): [True: 6.43k, False: 15.6k]
  ------------------
  311|  6.43k|                return static_cast<Value>(i);
  312|  6.43k|            }
  313|  22.1k|        }
  314|    368|        return SCALAR;
  315|  6.80k|    }
_ZN5glTF210AttribType16GetNumComponentsENS0_5ValueE:
  321|  22.8k|    inline static unsigned int GetNumComponents(Value type) {
  322|  22.8k|        return data<0>::infos[static_cast<size_t>(type)].numComponents;
  323|  22.8k|    }
_ZNK5glTF215CustomExtensioncvbEv:
  353|  14.3k|    operator bool() const {
  354|  14.3k|        return Size() != 0;
  355|  14.3k|    }
_ZNK5glTF215CustomExtension4SizeEv:
  357|  14.3k|    size_t Size() const {
  358|  14.3k|        if (mValues.isPresent) {
  ------------------
  |  Branch (358:13): [True: 0, False: 14.3k]
  ------------------
  359|      0|            return mValues.value.size();
  360|  14.3k|        } else if (mStringValue.isPresent || mDoubleValue.isPresent || mUint64Value.isPresent || mInt64Value.isPresent || mBoolValue.isPresent) {
  ------------------
  |  Branch (360:20): [True: 0, False: 14.3k]
  |  Branch (360:46): [True: 0, False: 14.3k]
  |  Branch (360:72): [True: 0, False: 14.3k]
  |  Branch (360:98): [True: 0, False: 14.3k]
  |  Branch (360:123): [True: 0, False: 14.3k]
  ------------------
  361|      0|            return 1;
  362|      0|        }
  363|  14.3k|        return 0;
  364|  14.3k|    }
_ZNK5glTF26Extras9HasExtrasEv:
  376|  14.3k|    inline bool HasExtras() const {
  377|  14.3k|        return !mValues.empty();
  378|  14.3k|    }
_ZN5glTF26Buffer10GetPointerEv:
  520|  5.96k|    uint8_t *GetPointer() { return mData.get(); }
_ZN5glTF26Buffer13MarkAsSpecialEv:
  522|  4.48k|    void MarkAsSpecial() { mIsSpecial = true; }
_ZN5glTF28Accessor7Indexer7GetUIntEi:
  596|  29.9k|        inline unsigned int GetUInt(int i) {
  597|  29.9k|            return GetValue<unsigned int>(i);
  598|  29.9k|        }
_ZNK5glTF28Accessor7Indexer7IsValidEv:
  600|  1.03k|        inline bool IsValid() const {
  601|  1.03k|            return data != nullptr;
  602|  1.03k|        }
_ZN5glTF28Accessor10GetIndexerEv:
  605|  1.04k|    inline Indexer GetIndexer() {
  606|  1.04k|        return Indexer(*this);
  607|  1.04k|    }
_ZNK5glTF25Image7HasDataEv:
  699|     95|    inline bool HasData() const { return mDataLength > 0; }
_ZNK5glTF25Image13GetDataLengthEv:
  701|     47|    inline size_t GetDataLength() const { return mDataLength; }
_ZN5glTF221PbrSpecularGlossinessC2Ev:
  754|  3.54k|    PbrSpecularGlossiness() { SetDefaults(); }
_ZN5glTF216MaterialSpecularC2Ev:
  764|  3.54k|    MaterialSpecular() { SetDefaults(); }
_ZN5glTF213MaterialSheenC2Ev:
  774|  3.54k|    MaterialSheen() { SetDefaults(); }
_ZN5glTF214MaterialVolumeC2Ev:
  797|  3.54k|    MaterialVolume() { SetDefaults(); }
_ZN5glTF211MaterialIORC2Ev:
  804|  3.54k|    MaterialIOR() { SetDefaults(); }
_ZN5glTF224MaterialEmissiveStrengthC2Ev:
  811|  3.54k|    MaterialEmissiveStrength() { SetDefaults(); }
_ZN5glTF218MaterialAnisotropyC2Ev:
  820|  3.54k|    MaterialAnisotropy() { SetDefaults(); }
_ZN5glTF28MaterialC2Ev:
  868|  3.54k|    Material() { SetDefaults(); }
_ZN5glTF24Mesh9PrimitiveC2Ev:
  901|  1.94k|        Primitive(): ngonEncoded(false) {}
_ZN5glTF27SamplerC2Ev:
  950|     59|    Sampler() { SetDefaults(); }
_ZN5glTF25AssetC2EPN6Assimp8IOSystemEPN9rapidjson36IGenericRemoteSchemaDocumentProviderINS4_21GenericSchemaDocumentINS4_12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEESB_EEEE:
 1179|  6.79k|            mDicts(),
 1180|  6.79k|            extensionsUsed(),
 1181|  6.79k|            extensionsRequired(),
 1182|  6.79k|            asset(),
 1183|  6.79k|            extras(nullptr),
 1184|  6.79k|            accessors(*this, "accessors"),
 1185|  6.79k|            animations(*this, "animations"),
 1186|  6.79k|            buffers(*this, "buffers"),
 1187|  6.79k|            bufferViews(*this, "bufferViews"),
 1188|  6.79k|            cameras(*this, "cameras"),
 1189|  6.79k|            lights(*this, "lights", "KHR_lights_punctual"),
 1190|  6.79k|            images(*this, "images"),
 1191|  6.79k|            materials(*this, "materials"),
 1192|  6.79k|            meshes(*this, "meshes"),
 1193|  6.79k|            nodes(*this, "nodes"),
 1194|  6.79k|            samplers(*this, "samplers"),
 1195|  6.79k|            scenes(*this, "scenes"),
 1196|  6.79k|            skins(*this, "skins"),
 1197|  6.79k|            textures(*this, "textures") ,
 1198|  6.79k|            mIOSystem(io),
 1199|  6.79k|            mSchemaDocumentProvider(schemaDocumentProvider) {
 1200|       |        // empty
 1201|  6.79k|    }
_ZN5glTF217ComponentTypeSizeENS_13ComponentTypeE:
  197|  22.3k|inline unsigned int ComponentTypeSize(ComponentType t) {
  198|  22.3k|    switch (t) {
  199|     62|    case ComponentType_SHORT:
  ------------------
  |  Branch (199:5): [True: 62, False: 22.3k]
  ------------------
  200|  3.13k|    case ComponentType_UNSIGNED_SHORT:
  ------------------
  |  Branch (200:5): [True: 3.07k, False: 19.3k]
  ------------------
  201|  3.13k|        return 2;
  202|       |
  203|  3.34k|    case ComponentType_UNSIGNED_INT:
  ------------------
  |  Branch (203:5): [True: 3.34k, False: 19.0k]
  ------------------
  204|  13.8k|    case ComponentType_FLOAT:
  ------------------
  |  Branch (204:5): [True: 10.5k, False: 11.8k]
  ------------------
  205|  13.8k|        return 4;
  206|       |
  207|  5.20k|    case ComponentType_BYTE:
  ------------------
  |  Branch (207:5): [True: 5.20k, False: 17.1k]
  ------------------
  208|  5.32k|    case ComponentType_UNSIGNED_BYTE:
  ------------------
  |  Branch (208:5): [True: 121, False: 22.2k]
  ------------------
  209|  5.32k|        return 1;
  210|     28|    default:
  ------------------
  |  Branch (210:5): [True: 28, False: 22.3k]
  ------------------
  211|     28|        throw DeadlyImportError("GLTF: Unsupported Component Type ", ai_to_string(t));
  212|  22.3k|    }
  213|  22.3k|}
_ZN5glTF226getContextForErrorMessagesERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEES8_:
 1244|     80|inline std::string getContextForErrorMessages(const std::string &id, const std::string &name) {
 1245|     80|    std::string context = id;
 1246|     80|    if (!name.empty()) {
  ------------------
  |  Branch (1246:9): [True: 12, False: 68]
  ------------------
 1247|     12|        context += " (\"" + name + "\")";
 1248|     12|    }
 1249|     80|    return context;
 1250|     80|}
_ZN5glTF25Asset10ExtensionsC2Ev:
 1142|  6.79k|        Extensions() = default;
_ZN5glTF25Asset18RequiredExtensionsC2Ev:
 1152|  6.79k|        RequiredExtensions() = default;
_ZN5glTF213AssetMetadataC2Ev:
 1104|  6.79k|    AssetMetadata() = default;
_ZN5glTF212LazyDictBaseD2Ev:
 1026|  95.1k|    virtual ~LazyDictBase() = default;
_ZN5glTF215CustomExtensionC2Ev:
  366|  70.9k|    CustomExtension() = default;
_ZN5glTF215CustomExtensionC2ERKS0_:
  368|  30.7k|    CustomExtension(const CustomExtension &other) = default;
_ZN5glTF215CustomExtensionaSERKS0_:
  369|  1.90k|    CustomExtension& operator=(const CustomExtension&) = default;
_ZN5glTF25SceneC2Ev:
  959|  2.16k|    Scene() = default;
_ZN5glTF24NodeC2Ev:
  935|  11.5k|    Node() = default;
_ZN5glTF24MeshC2Ev:
  909|  1.95k|    Mesh() = default;
_ZN5glTF28AccessorC2Ev:
  609|  7.08k|    Accessor() = default;
_ZN5glTF27TextureC2Ev:
  989|     74|    Texture() = default;
_ZN5glTF24SkinC2Ev:
  974|    369|    Skin() = default;
_ZNK5glTF28LazyDictINS_8MaterialEE4SizeEv:
 1086|  2.00k|    inline unsigned int Size() const { return unsigned(mObjs.size()); }
_ZN5glTF28LazyDictINS_8MaterialEEixEm:
 1088|  1.39k|    inline T &operator[](size_t i) { return *mObjs[i]; }
_ZNK5glTF28LazyDictINS_4MeshEE4SizeEv:
 1086|  11.2k|    inline unsigned int Size() const { return unsigned(mObjs.size()); }
_ZN5glTF28LazyDictINS_4MeshEEixEm:
 1088|  3.50k|    inline T &operator[](size_t i) { return *mObjs[i]; }
_ZNK5glTF28LazyDictINS_6CameraEE4SizeEv:
 1086|  1.70k|    inline unsigned int Size() const { return unsigned(mObjs.size()); }
_ZNK5glTF28LazyDictINS_5LightEE4SizeEv:
 1086|  1.70k|    inline unsigned int Size() const { return unsigned(mObjs.size()); }
_ZNK5glTF28LazyDictINS_9AnimationEE4SizeEv:
 1086|  1.53k|    inline unsigned int Size() const { return unsigned(mObjs.size()); }
_ZNK5glTF28LazyDictINS_5ImageEE4SizeEv:
 1086|  4.14k|    inline unsigned int Size() const { return unsigned(mObjs.size()); }
_ZN5glTF28LazyDictINS_5ImageEEixEm:
 1088|     95|    inline T &operator[](size_t i) { return *mObjs[i]; }

_ZN5glTF26BufferD2Ev:
  565|  4.48k|inline Buffer::~Buffer() {
  566|  4.48k|    for (SEncodedRegion *reg : EncodedRegion_List) delete reg;
  ------------------
  |  Branch (566:30): [True: 0, False: 4.48k]
  ------------------
  567|  4.48k|}
_ZN5glTF26Object10FindStringERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEEPKc:
  235|  2.27k|inline Value *Object::FindString(Value &val, const char *memberId) {
  236|  2.27k|    return FindStringInContext(val, memberId, id.c_str(), name.c_str());
  237|  2.27k|}
_ZN5glTF26Object8FindUIntERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEEPKc:
  243|  58.7k|inline Value *Object::FindUInt(Value &val, const char *memberId) {
  244|  58.7k|    return FindUIntInContext(val, memberId, id.c_str(), name.c_str());
  245|  58.7k|}
_ZN5glTF26Object9FindArrayERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEEPKc:
  247|  30.8k|inline Value *Object::FindArray(Value &val, const char *memberId) {
  248|  30.8k|    return FindArrayInContext(val, memberId, id.c_str(), name.c_str());
  249|  30.8k|}
_ZN5glTF26Object10FindObjectERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEEPKc:
  251|  87.4k|inline Value *Object::FindObject(Value &val, const char *memberId) {
  252|  87.4k|    return FindObjectInContext(val, memberId, id.c_str(), name.c_str());
  253|  87.4k|}
_ZN5glTF26Object14ReadExtensionsERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEE:
  259|  30.4k|inline void Object::ReadExtensions(Value &val) {
  260|  30.4k|    if (Value *curExtensions = FindObject(val, "extensions")) {
  ------------------
  |  Branch (260:16): [True: 0, False: 30.4k]
  ------------------
  261|      0|        this->customExtensions = glTF2::ReadExtensions("extensions", *curExtensions);
  262|      0|    }
  263|  30.4k|}
_ZN5glTF26Object10ReadExtrasERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEE:
  265|  30.4k|inline void Object::ReadExtras(Value &val) {
  266|  30.4k|    if (Value *curExtras = FindObject(val, "extras")) {
  ------------------
  |  Branch (266:16): [True: 7.56k, False: 22.8k]
  ------------------
  267|  7.56k|        this->extras = glTF2::ReadExtras(*curExtras);
  268|  7.56k|    }
  269|  30.4k|}
_ZN5glTF26Buffer14LoadFromStreamERN6Assimp8IOStreamEmm:
  625|  2.02k|inline bool Buffer::LoadFromStream(IOStream &stream, size_t length, size_t baseOffset) {
  626|  2.02k|    byteLength = length ? length : stream.FileSize();
  ------------------
  |  Branch (626:18): [True: 2.02k, False: 0]
  ------------------
  627|       |
  628|  2.02k|    if (byteLength > stream.FileSize()) {
  ------------------
  |  Branch (628:9): [True: 54, False: 1.96k]
  ------------------
  629|     54|        throw DeadlyImportError("GLTF: Invalid byteLength exceeds size of actual data.");
  630|     54|    }
  631|       |
  632|  1.96k|    if (baseOffset) {
  ------------------
  |  Branch (632:9): [True: 1.96k, False: 0]
  ------------------
  633|  1.96k|        stream.Seek(baseOffset, aiOrigin_SET);
  634|  1.96k|    }
  635|       |
  636|  1.96k|    mData.reset(new uint8_t[byteLength], std::default_delete<uint8_t[]>());
  637|       |
  638|  1.96k|    if (stream.Read(mData.get(), byteLength, 1) != 1) {
  ------------------
  |  Branch (638:9): [True: 15, False: 1.95k]
  ------------------
  639|     15|        return false;
  640|     15|    }
  641|  1.95k|    return true;
  642|  1.96k|}
_ZN5glTF210BufferView4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
  765|  6.70k|inline void BufferView::Read(Value &obj, Asset &r) {
  766|  6.70k|    if (Value *bufferVal = FindUInt(obj, "buffer")) {
  ------------------
  |  Branch (766:16): [True: 6.69k, False: 12]
  ------------------
  767|  6.69k|        buffer = r.buffers.Retrieve(bufferVal->GetUint());
  768|  6.69k|    }
  769|       |
  770|  6.70k|    if (!buffer) {
  ------------------
  |  Branch (770:9): [True: 9, False: 6.69k]
  ------------------
  771|      9|        throw DeadlyImportError("GLTF: Buffer view without valid buffer.");
  772|      9|    }
  773|       |
  774|  6.69k|    byteOffset = MemberOrDefault(obj, "byteOffset", size_t(0));
  775|  6.69k|    byteLength = MemberOrDefault(obj, "byteLength", size_t(0));
  776|  6.69k|    byteStride = MemberOrDefault(obj, "byteStride", 0u);
  777|       |
  778|       |    // Check length
  779|  6.69k|    if ((byteOffset + byteLength) > buffer->byteLength) {
  ------------------
  |  Branch (779:9): [True: 19, False: 6.67k]
  ------------------
  780|     19|        throw DeadlyImportError("GLTF: Buffer view with offset/length (", byteOffset, "/", byteLength, ") is out of range.");
  781|     19|    }
  782|  6.69k|}
_ZN5glTF28Accessor4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
  871|  7.08k|inline void Accessor::Read(Value &obj, Asset &r) {
  872|  7.08k|    if (Value *bufferViewVal = FindUInt(obj, "bufferView")) {
  ------------------
  |  Branch (872:16): [True: 6.92k, False: 158]
  ------------------
  873|  6.92k|        bufferView = r.bufferViews.Retrieve(bufferViewVal->GetUint());
  874|  6.92k|    }
  875|       |
  876|  7.08k|    byteOffset = MemberOrDefault(obj, "byteOffset", size_t(0));
  877|  7.08k|    componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE);
  878|  7.08k|    {
  879|  7.08k|        const Value *countValue = FindUInt(obj, "count");
  880|  7.08k|        if (!countValue) {
  ------------------
  |  Branch (880:13): [True: 8, False: 7.07k]
  ------------------
  881|      8|            throw DeadlyImportError("A count value is required, when reading ", id.c_str(), name.empty() ? "" : " (" + name + ")");
  ------------------
  |  Branch (881:93): [True: 7, False: 1]
  ------------------
  882|      8|        }
  883|  7.07k|        count = countValue->GetUint();
  884|  7.07k|    }
  885|       |
  886|      0|    const char *typestr;
  887|  7.07k|    type = ReadMember(obj, "type", typestr) ? AttribType::FromString(typestr) : AttribType::SCALAR;
  ------------------
  |  Branch (887:12): [True: 6.80k, False: 274]
  ------------------
  888|       |
  889|  7.07k|    if (bufferView) {
  ------------------
  |  Branch (889:9): [True: 6.87k, False: 208]
  ------------------
  890|       |        // Check length
  891|  6.87k|        unsigned long long byteLength = count > 0
  ------------------
  |  Branch (891:41): [True: 6.85k, False: 20]
  ------------------
  892|  6.87k|            ? (unsigned long long)GetStride() * (unsigned long long)(count - 1) + (unsigned long long)GetElementSize()
  893|  6.87k|            : 0;
  894|       |
  895|       |        // handle integer overflow
  896|  6.87k|        if (byteLength < count) {
  ------------------
  |  Branch (896:13): [True: 0, False: 6.87k]
  ------------------
  897|      0|            throw DeadlyImportError("GLTF: Accessor with offset/count (", byteOffset, "/", count, ") is out of range.");
  898|      0|        }
  899|       |
  900|  6.87k|        if ((byteOffset + byteLength) > bufferView->byteLength || (bufferView->byteOffset + byteOffset + byteLength) > bufferView->buffer->byteLength) {
  ------------------
  |  Branch (900:13): [True: 66, False: 6.80k]
  |  Branch (900:67): [True: 0, False: 6.80k]
  ------------------
  901|     48|            throw DeadlyImportError("GLTF: Accessor with offset/length (", byteOffset, "/", byteLength, ") is out of range.");
  902|     48|        }
  903|  6.87k|    }
  904|       |
  905|  7.03k|    if (Value *sparseValue = FindObject(obj, "sparse")) {
  ------------------
  |  Branch (905:16): [True: 0, False: 7.03k]
  ------------------
  906|      0|        sparse.reset(new Sparse);
  907|       |        // count
  908|      0|        ReadMember(*sparseValue, "count", sparse->count);
  909|       |
  910|       |        // indices
  911|      0|        if (Value *indicesValue = FindObject(*sparseValue, "indices")) {
  ------------------
  |  Branch (911:20): [True: 0, False: 0]
  ------------------
  912|       |            //indices bufferView
  913|      0|            Value *indiceViewID = FindUInt(*indicesValue, "bufferView");
  914|      0|            if (!indiceViewID) {
  ------------------
  |  Branch (914:17): [True: 0, False: 0]
  ------------------
  915|      0|                throw DeadlyImportError("A bufferView value is required, when reading ", id.c_str(), name.empty() ? "" : " (" + name + ")");
  ------------------
  |  Branch (915:102): [True: 0, False: 0]
  ------------------
  916|      0|            }
  917|      0|            sparse->indices = r.bufferViews.Retrieve(indiceViewID->GetUint());
  918|       |            //indices byteOffset
  919|      0|            sparse->indicesByteOffset = MemberOrDefault(*indicesValue, "byteOffset", size_t(0));
  920|       |            //indices componentType
  921|      0|            sparse->indicesType = MemberOrDefault(*indicesValue, "componentType", ComponentType_BYTE);
  922|       |            //sparse->indices->Read(*indicesValue, r);
  923|      0|        } else {
  924|       |            // indicesType
  925|      0|            sparse->indicesType = MemberOrDefault(*sparseValue, "componentType", ComponentType_UNSIGNED_SHORT);
  926|      0|        }
  927|       |
  928|       |        // value
  929|      0|        if (Value *valuesValue = FindObject(*sparseValue, "values")) {
  ------------------
  |  Branch (929:20): [True: 0, False: 0]
  ------------------
  930|       |            //value bufferView
  931|      0|            Value *valueViewID = FindUInt(*valuesValue, "bufferView");
  932|      0|            if (!valueViewID) {
  ------------------
  |  Branch (932:17): [True: 0, False: 0]
  ------------------
  933|      0|                throw DeadlyImportError("A bufferView value is required, when reading ", id.c_str(), name.empty() ? "" : " (" + name + ")");
  ------------------
  |  Branch (933:102): [True: 0, False: 0]
  ------------------
  934|      0|            }
  935|      0|            sparse->values = r.bufferViews.Retrieve(valueViewID->GetUint());
  936|       |            //value byteOffset
  937|      0|            sparse->valuesByteOffset = MemberOrDefault(*valuesValue, "byteOffset", size_t(0));
  938|       |            //sparse->values->Read(*valuesValue, r);
  939|      0|        }
  940|       |
  941|       |
  942|      0|        const unsigned int elementSize = GetElementSize();
  943|      0|        const size_t dataSize = count * elementSize;
  944|      0|        if (bufferView) {
  ------------------
  |  Branch (944:13): [True: 0, False: 0]
  ------------------
  945|      0|            size_t bufferViewTailSize;
  946|      0|            const uint8_t* bufferViewPointer = bufferView->GetPointerAndTailSize(byteOffset, bufferViewTailSize);
  947|      0|            if (dataSize > bufferViewTailSize) {
  ------------------
  |  Branch (947:17): [True: 0, False: 0]
  ------------------
  948|      0|                throw DeadlyImportError("Invalid buffer when reading ", id.c_str(), name.empty() ? "" : " (" + name + ")");
  ------------------
  |  Branch (948:85): [True: 0, False: 0]
  ------------------
  949|      0|            }
  950|      0|            sparse->PopulateData(dataSize, bufferViewPointer);
  951|      0|        }
  952|      0|        else {
  953|      0|            sparse->PopulateData(dataSize, nullptr);
  954|      0|        }
  955|      0|        sparse->PatchData(elementSize);
  956|      0|    }
  957|  7.03k|}
_ZN5glTF28Accessor16GetNumComponentsEv:
  959|  22.8k|inline unsigned int Accessor::GetNumComponents() {
  960|  22.8k|    return AttribType::GetNumComponents(type);
  961|  22.8k|}
_ZN5glTF28Accessor20GetBytesPerComponentEv:
  963|  22.3k|inline unsigned int Accessor::GetBytesPerComponent() {
  964|  22.3k|    return int(ComponentTypeSize(componentType));
  965|  22.3k|}
_ZN5glTF28Accessor14GetElementSizeEv:
  967|  22.3k|inline unsigned int Accessor::GetElementSize() {
  968|  22.3k|    return GetNumComponents() * GetBytesPerComponent();
  969|  22.3k|}
_ZN5glTF28Accessor10GetPointerEv:
  971|  5.97k|inline uint8_t *Accessor::GetPointer() {
  972|  5.97k|    if (decodedBuffer)
  ------------------
  |  Branch (972:9): [True: 0, False: 5.97k]
  ------------------
  973|      0|        return decodedBuffer->GetPointer();
  974|       |
  975|  5.97k|    if (sparse)
  ------------------
  |  Branch (975:9): [True: 0, False: 5.97k]
  ------------------
  976|      0|        return sparse->data.data();
  977|       |
  978|  5.97k|    if (!bufferView || !bufferView->buffer) return nullptr;
  ------------------
  |  Branch (978:9): [True: 66, False: 5.91k]
  |  Branch (978:24): [True: 0, False: 5.91k]
  ------------------
  979|  5.91k|    uint8_t *basePtr = bufferView->buffer->GetPointer();
  980|  5.91k|    if (!basePtr) return nullptr;
  ------------------
  |  Branch (980:9): [True: 0, False: 5.91k]
  ------------------
  981|       |
  982|  5.91k|    size_t offset = byteOffset + bufferView->byteOffset;
  983|       |
  984|       |    // Check if region is encoded.
  985|  5.91k|    if (bufferView->buffer->EncodedRegion_Current != nullptr) {
  ------------------
  |  Branch (985:9): [True: 0, False: 5.91k]
  ------------------
  986|      0|        const size_t begin = bufferView->buffer->EncodedRegion_Current->Offset;
  987|      0|        const size_t end = begin + bufferView->buffer->EncodedRegion_Current->DecodedData_Length;
  988|       |
  989|      0|        if ((offset >= begin) && (offset < end))
  ------------------
  |  Branch (989:13): [True: 0, False: 0]
  |  Branch (989:34): [True: 0, False: 0]
  ------------------
  990|      0|            return &bufferView->buffer->EncodedRegion_Current->DecodedData[offset - begin];
  991|      0|    }
  992|       |
  993|  5.91k|    return basePtr + offset;
  994|  5.91k|}
_ZN5glTF28Accessor9GetStrideEv:
  996|  12.7k|inline size_t Accessor::GetStride() {
  997|       |    // Decoded buffer is always packed
  998|  12.7k|    if (decodedBuffer)
  ------------------
  |  Branch (998:9): [True: 0, False: 12.7k]
  ------------------
  999|      0|        return GetElementSize();
 1000|       |
 1001|       |    // Sparse and normal bufferView
 1002|  12.7k|    return (bufferView && bufferView->byteStride ? bufferView->byteStride : GetElementSize());
  ------------------
  |  Branch (1002:13): [True: 12.7k, False: 11]
  |  Branch (1002:27): [True: 3.39k, False: 9.36k]
  ------------------
 1003|  12.7k|}
_ZN5glTF28Accessor14GetMaxByteSizeEv:
 1005|  34.8k|inline size_t Accessor::GetMaxByteSize() {
 1006|  34.8k|    if (decodedBuffer)
  ------------------
  |  Branch (1006:9): [True: 0, False: 34.8k]
  ------------------
 1007|      0|        return decodedBuffer->byteLength;
 1008|       |
 1009|  34.8k|    if (sparse) {
  ------------------
  |  Branch (1009:9): [True: 0, False: 34.8k]
  ------------------
 1010|      0|        return sparse->data.size();
 1011|      0|    }
 1012|       |
 1013|  34.8k|    if (bufferView) {
  ------------------
  |  Branch (1013:9): [True: 34.8k, False: 0]
  ------------------
 1014|  34.8k|        return byteOffset <= bufferView->byteLength ? bufferView->byteLength - byteOffset : 0;
  ------------------
  |  Branch (1014:16): [True: 34.8k, False: 0]
  ------------------
 1015|  34.8k|    }
 1016|       |
 1017|      0|    return 0;
 1018|  34.8k|}
_ZN5glTF25Image4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
 1142|     60|inline void Image::Read(Value &obj, Asset &r) {
 1143|       |    //basisu: no need to handle .ktx2, .basis, load as is
 1144|     60|    if (!mDataLength) {
  ------------------
  |  Branch (1144:9): [True: 60, False: 0]
  ------------------
 1145|     60|        Value *curUri = FindString(obj, "uri");
 1146|     60|        if (nullptr != curUri) {
  ------------------
  |  Branch (1146:13): [True: 0, False: 60]
  ------------------
 1147|      0|            const char *uristr = curUri->GetString();
 1148|       |
 1149|      0|            glTFCommon::Util::DataURI dataURI;
 1150|      0|            if (ParseDataURI(uristr, curUri->GetStringLength(), dataURI)) {
  ------------------
  |  Branch (1150:17): [True: 0, False: 0]
  ------------------
 1151|      0|                mimeType = dataURI.mediaType;
 1152|      0|                if (dataURI.base64) {
  ------------------
  |  Branch (1152:21): [True: 0, False: 0]
  ------------------
 1153|      0|                    uint8_t *ptr = nullptr;
 1154|      0|                    mDataLength = Base64::Decode(dataURI.data, dataURI.dataLength, ptr);
 1155|      0|                    mData.reset(ptr);
 1156|      0|                }
 1157|      0|            } else {
 1158|      0|                this->uri = uristr;
 1159|      0|            }
 1160|     60|        } else if (Value *bufferViewVal = FindUInt(obj, "bufferView")) {
  ------------------
  |  Branch (1160:27): [True: 59, False: 1]
  ------------------
 1161|     59|            this->bufferView = r.bufferViews.Retrieve(bufferViewVal->GetUint());
 1162|     59|            if (Value *mtype = FindString(obj, "mimeType")) {
  ------------------
  |  Branch (1162:24): [True: 55, False: 4]
  ------------------
 1163|     55|                this->mimeType = mtype->GetString();
 1164|     55|            }
 1165|     59|            if (!this->bufferView || this->mimeType.empty()) {
  ------------------
  |  Branch (1165:17): [True: 3, False: 56]
  |  Branch (1165:38): [True: 1, False: 55]
  ------------------
 1166|      1|                throw DeadlyImportError("GLTF2: ", getContextForErrorMessages(id, name), " does not have a URI, so it must have a valid bufferView and mimetype");
 1167|      1|            }
 1168|       |
 1169|     58|            Ref<Buffer> buffer = this->bufferView->buffer;
 1170|       |
 1171|     58|            this->mDataLength = this->bufferView->byteLength;
 1172|       |            // maybe this memcpy could be avoided if aiTexture does not delete[] pcData at destruction.
 1173|       |
 1174|     58|            this->mData.reset(new uint8_t[this->mDataLength]);
 1175|     58|            memcpy(this->mData.get(), buffer->GetPointer() + this->bufferView->byteOffset, this->mDataLength);
 1176|     58|        } else {
 1177|      1|            throw DeadlyImportError("GLTF2: ", getContextForErrorMessages(id, name), " should have either a URI of a bufferView and mimetype");
 1178|      1|        }
 1179|     60|    }
 1180|     60|}
_ZN5glTF25Image9StealDataEv:
 1182|     47|inline uint8_t *Image::StealData() {
 1183|     47|    mDataLength = 0;
 1184|     47|    return mData.release();
 1185|     47|}
_ZN5glTF27Sampler4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
 1205|     59|inline void Sampler::Read(Value &obj, Asset & /*r*/) {
 1206|     59|    SetDefaults();
 1207|       |
 1208|     59|    ReadMember(obj, "name", name);
 1209|     59|    ReadMember(obj, "magFilter", magFilter);
 1210|     59|    ReadMember(obj, "minFilter", minFilter);
 1211|     59|    ReadMember(obj, "wrapS", wrapS);
 1212|     59|    ReadMember(obj, "wrapT", wrapT);
 1213|     59|}
_ZN5glTF27Sampler11SetDefaultsEv:
 1215|    118|inline void Sampler::SetDefaults() {
 1216|       |    //only wrapping modes have defaults
 1217|    118|    wrapS = SamplerWrap::Repeat;
 1218|    118|    wrapT = SamplerWrap::Repeat;
 1219|    118|    magFilter = SamplerMagFilter::UNSET;
 1220|    118|    minFilter = SamplerMinFilter::UNSET;
 1221|    118|}
_ZN5glTF27Texture4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
 1223|     74|inline void Texture::Read(Value &obj, Asset &r) {
 1224|     74|    if (Value *sourceVal = FindUInt(obj, "source")) {
  ------------------
  |  Branch (1224:16): [True: 62, False: 12]
  ------------------
 1225|     62|        source = r.images.Retrieve(sourceVal->GetUint());
 1226|     62|    }
 1227|       |
 1228|     74|    if (Value *samplerVal = FindUInt(obj, "sampler")) {
  ------------------
  |  Branch (1228:16): [True: 61, False: 13]
  ------------------
 1229|     61|        sampler = r.samplers.Retrieve(samplerVal->GetUint());
 1230|     61|    }
 1231|       |
 1232|     74|    if (Value *extensions = FindObject(obj, "extensions")) {
  ------------------
  |  Branch (1232:16): [True: 0, False: 74]
  ------------------
 1233|      0|        if (r.extensionsUsed.KHR_texture_basisu) {
  ------------------
  |  Branch (1233:13): [True: 0, False: 0]
  ------------------
 1234|      0|            if (Value *curBasisU = FindObject(*extensions, "KHR_texture_basisu")) {
  ------------------
  |  Branch (1234:24): [True: 0, False: 0]
  ------------------
 1235|       |
 1236|      0|                if (Value *sourceVal = FindUInt(*curBasisU, "source")) {
  ------------------
  |  Branch (1236:28): [True: 0, False: 0]
  ------------------
 1237|      0|                    source = r.images.Retrieve(sourceVal->GetUint());
 1238|      0|                }
 1239|      0|            }
 1240|      0|        } else if(r.extensionsUsed.EXT_texture_webp) {
  ------------------
  |  Branch (1240:19): [True: 0, False: 0]
  ------------------
 1241|      0|            if (Value *curBasisU = FindObject(*extensions, "EXT_texture_webp")) {
  ------------------
  |  Branch (1241:24): [True: 0, False: 0]
  ------------------
 1242|       |
 1243|      0|                if (Value *sourceVal = FindUInt(*curBasisU, "source")) {
  ------------------
  |  Branch (1243:28): [True: 0, False: 0]
  ------------------
 1244|      0|                    source = r.images.Retrieve(sourceVal->GetUint());
 1245|      0|                }
 1246|      0|            }
 1247|      0|        }
 1248|      0|    }
 1249|     74|}
_ZN5glTF28Material20SetTexturePropertiesERNS_5AssetEPN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEERNS_11TextureInfoE:
 1251|     79|void Material::SetTextureProperties(Asset &r, Value *prop, TextureInfo &out) {
 1252|     79|    if (r.extensionsUsed.KHR_texture_transform) {
  ------------------
  |  Branch (1252:9): [True: 0, False: 79]
  ------------------
 1253|      0|        if (Value *pKHR_texture_transform = FindExtension(*prop, "KHR_texture_transform")) {
  ------------------
  |  Branch (1253:20): [True: 0, False: 0]
  ------------------
 1254|      0|            out.textureTransformSupported = true;
 1255|      0|            if (Value *array = FindArray(*pKHR_texture_transform, "offset")) {
  ------------------
  |  Branch (1255:24): [True: 0, False: 0]
  ------------------
 1256|      0|                out.TextureTransformExt_t.offset[0] = (*array)[0].GetFloat();
 1257|      0|                out.TextureTransformExt_t.offset[1] = (*array)[1].GetFloat();
 1258|      0|            } else {
 1259|      0|                out.TextureTransformExt_t.offset[0] = 0;
 1260|      0|                out.TextureTransformExt_t.offset[1] = 0;
 1261|      0|            }
 1262|       |
 1263|      0|            if (!ReadMember(*pKHR_texture_transform, "rotation", out.TextureTransformExt_t.rotation)) {
  ------------------
  |  Branch (1263:17): [True: 0, False: 0]
  ------------------
 1264|      0|                out.TextureTransformExt_t.rotation = 0;
 1265|      0|            }
 1266|       |
 1267|      0|            if (Value *array = FindArray(*pKHR_texture_transform, "scale")) {
  ------------------
  |  Branch (1267:24): [True: 0, False: 0]
  ------------------
 1268|      0|                out.TextureTransformExt_t.scale[0] = (*array)[0].GetFloat();
 1269|      0|                out.TextureTransformExt_t.scale[1] = (*array)[1].GetFloat();
 1270|      0|            } else {
 1271|      0|                out.TextureTransformExt_t.scale[0] = 1;
 1272|      0|                out.TextureTransformExt_t.scale[1] = 1;
 1273|      0|            }
 1274|      0|        }
 1275|      0|    }
 1276|       |
 1277|     79|    if (Value *indexProp = FindUInt(*prop, "index")) {
  ------------------
  |  Branch (1277:16): [True: 77, False: 2]
  ------------------
 1278|     77|        out.texture = r.textures.Retrieve(indexProp->GetUint());
 1279|     77|    }
 1280|       |
 1281|     79|    if (Value *texcoord = FindUInt(*prop, "texCoord")) {
  ------------------
  |  Branch (1281:16): [True: 0, False: 79]
  ------------------
 1282|      0|        out.texCoord = texcoord->GetUint();
 1283|      0|    }
 1284|     79|}
_ZN5glTF28Material19ReadTexturePropertyERNS_5AssetERN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEEPKcRNS_11TextureInfoE:
 1286|  3.68k|inline void Material::ReadTextureProperty(Asset &r, Value &vals, const char *propName, TextureInfo &out) {
 1287|  3.68k|    if (Value *prop = FindMember(vals, propName)) {
  ------------------
  |  Branch (1287:16): [True: 79, False: 3.60k]
  ------------------
 1288|     79|        SetTextureProperties(r, prop, out);
 1289|     79|    }
 1290|  3.68k|}
_ZN5glTF28Material19ReadTexturePropertyERNS_5AssetERN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEEPKcRNS_17NormalTextureInfoE:
 1292|  1.52k|inline void Material::ReadTextureProperty(Asset &r, Value &vals, const char *propName, NormalTextureInfo &out) {
 1293|  1.52k|    if (Value *prop = FindMember(vals, propName)) {
  ------------------
  |  Branch (1293:16): [True: 0, False: 1.52k]
  ------------------
 1294|      0|        SetTextureProperties(r, prop, out);
 1295|       |
 1296|      0|        if (Value *scale = FindNumber(*prop, "scale")) {
  ------------------
  |  Branch (1296:20): [True: 0, False: 0]
  ------------------
 1297|      0|            out.scale = static_cast<float>(scale->GetDouble());
 1298|      0|        }
 1299|      0|    }
 1300|  1.52k|}
_ZN5glTF28Material19ReadTexturePropertyERNS_5AssetERN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEEPKcRNS_20OcclusionTextureInfoE:
 1302|  1.52k|inline void Material::ReadTextureProperty(Asset &r, Value &vals, const char *propName, OcclusionTextureInfo &out) {
 1303|  1.52k|    if (Value *prop = FindMember(vals, propName)) {
  ------------------
  |  Branch (1303:16): [True: 0, False: 1.52k]
  ------------------
 1304|      0|        SetTextureProperties(r, prop, out);
 1305|       |
 1306|      0|        if (Value *strength = FindNumber(*prop, "strength")) {
  ------------------
  |  Branch (1306:20): [True: 0, False: 0]
  ------------------
 1307|      0|            out.strength = static_cast<float>(strength->GetDouble());
 1308|      0|        }
 1309|      0|    }
 1310|  1.52k|}
_ZN5glTF28Material4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
 1312|  1.54k|inline void Material::Read(Value &material, Asset &r) {
 1313|  1.54k|    SetDefaults();
 1314|       |
 1315|  1.54k|    if (Value *curPbrMetallicRoughness = FindObject(material, "pbrMetallicRoughness")) {
  ------------------
  |  Branch (1315:16): [True: 1.08k, False: 457]
  ------------------
 1316|  1.08k|        ReadMember(*curPbrMetallicRoughness, "baseColorFactor", this->pbrMetallicRoughness.baseColorFactor);
 1317|  1.08k|        ReadTextureProperty(r, *curPbrMetallicRoughness, "baseColorTexture", this->pbrMetallicRoughness.baseColorTexture);
 1318|  1.08k|        ReadTextureProperty(r, *curPbrMetallicRoughness, "metallicRoughnessTexture", this->pbrMetallicRoughness.metallicRoughnessTexture);
 1319|  1.08k|        ReadMember(*curPbrMetallicRoughness, "metallicFactor", this->pbrMetallicRoughness.metallicFactor);
 1320|  1.08k|        ReadMember(*curPbrMetallicRoughness, "roughnessFactor", this->pbrMetallicRoughness.roughnessFactor);
 1321|  1.08k|    }
 1322|       |
 1323|  1.54k|    ReadTextureProperty(r, material, "normalTexture", this->normalTexture);
 1324|  1.54k|    ReadTextureProperty(r, material, "occlusionTexture", this->occlusionTexture);
 1325|  1.54k|    ReadTextureProperty(r, material, "emissiveTexture", this->emissiveTexture);
 1326|  1.54k|    ReadMember(material, "emissiveFactor", this->emissiveFactor);
 1327|       |
 1328|  1.54k|    ReadMember(material, "doubleSided", this->doubleSided);
 1329|  1.54k|    ReadMember(material, "alphaMode", this->alphaMode);
 1330|  1.54k|    ReadMember(material, "alphaCutoff", this->alphaCutoff);
 1331|       |
 1332|  1.54k|    if (Value *extensions = FindObject(material, "extensions")) {
  ------------------
  |  Branch (1332:16): [True: 0, False: 1.54k]
  ------------------
 1333|      0|        if (r.extensionsUsed.KHR_materials_pbrSpecularGlossiness) {
  ------------------
  |  Branch (1333:13): [True: 0, False: 0]
  ------------------
 1334|      0|            if (Value *curPbrSpecularGlossiness = FindObject(*extensions, "KHR_materials_pbrSpecularGlossiness")) {
  ------------------
  |  Branch (1334:24): [True: 0, False: 0]
  ------------------
 1335|      0|                PbrSpecularGlossiness pbrSG;
 1336|       |
 1337|      0|                ReadMember(*curPbrSpecularGlossiness, "diffuseFactor", pbrSG.diffuseFactor);
 1338|      0|                ReadTextureProperty(r, *curPbrSpecularGlossiness, "diffuseTexture", pbrSG.diffuseTexture);
 1339|      0|                ReadTextureProperty(r, *curPbrSpecularGlossiness, "specularGlossinessTexture", pbrSG.specularGlossinessTexture);
 1340|      0|                ReadMember(*curPbrSpecularGlossiness, "specularFactor", pbrSG.specularFactor);
 1341|      0|                ReadMember(*curPbrSpecularGlossiness, "glossinessFactor", pbrSG.glossinessFactor);
 1342|       |
 1343|      0|                this->pbrSpecularGlossiness = Nullable<PbrSpecularGlossiness>(pbrSG);
 1344|      0|            }
 1345|      0|        }
 1346|       |
 1347|      0|        if (r.extensionsUsed.KHR_materials_specular) {
  ------------------
  |  Branch (1347:13): [True: 0, False: 0]
  ------------------
 1348|      0|            if (Value *curMatSpecular = FindObject(*extensions, "KHR_materials_specular")) {
  ------------------
  |  Branch (1348:24): [True: 0, False: 0]
  ------------------
 1349|      0|                MaterialSpecular specular;
 1350|       |
 1351|      0|                ReadMember(*curMatSpecular, "specularFactor", specular.specularFactor);
 1352|      0|                ReadTextureProperty(r, *curMatSpecular, "specularTexture", specular.specularTexture);
 1353|      0|                ReadMember(*curMatSpecular, "specularColorFactor", specular.specularColorFactor);
 1354|      0|                ReadTextureProperty(r, *curMatSpecular, "specularColorTexture", specular.specularColorTexture);
 1355|       |
 1356|      0|                this->materialSpecular = Nullable<MaterialSpecular>(specular);
 1357|      0|            }
 1358|      0|        }
 1359|       |
 1360|       |        // Extension KHR_texture_transform is handled in ReadTextureProperty
 1361|       |
 1362|      0|        if (r.extensionsUsed.KHR_materials_sheen) {
  ------------------
  |  Branch (1362:13): [True: 0, False: 0]
  ------------------
 1363|      0|            if (Value *curMaterialSheen = FindObject(*extensions, "KHR_materials_sheen")) {
  ------------------
  |  Branch (1363:24): [True: 0, False: 0]
  ------------------
 1364|      0|                MaterialSheen sheen;
 1365|       |
 1366|      0|                ReadMember(*curMaterialSheen, "sheenColorFactor", sheen.sheenColorFactor);
 1367|      0|                ReadTextureProperty(r, *curMaterialSheen, "sheenColorTexture", sheen.sheenColorTexture);
 1368|      0|                ReadMember(*curMaterialSheen, "sheenRoughnessFactor", sheen.sheenRoughnessFactor);
 1369|      0|                ReadTextureProperty(r, *curMaterialSheen, "sheenRoughnessTexture", sheen.sheenRoughnessTexture);
 1370|       |
 1371|      0|                this->materialSheen = Nullable<MaterialSheen>(sheen);
 1372|      0|            }
 1373|      0|        }
 1374|       |
 1375|      0|        if (r.extensionsUsed.KHR_materials_clearcoat) {
  ------------------
  |  Branch (1375:13): [True: 0, False: 0]
  ------------------
 1376|      0|            if (Value *curMaterialClearcoat = FindObject(*extensions, "KHR_materials_clearcoat")) {
  ------------------
  |  Branch (1376:24): [True: 0, False: 0]
  ------------------
 1377|      0|                MaterialClearcoat clearcoat;
 1378|       |
 1379|      0|                ReadMember(*curMaterialClearcoat, "clearcoatFactor", clearcoat.clearcoatFactor);
 1380|      0|                ReadTextureProperty(r, *curMaterialClearcoat, "clearcoatTexture", clearcoat.clearcoatTexture);
 1381|      0|                ReadMember(*curMaterialClearcoat, "clearcoatRoughnessFactor", clearcoat.clearcoatRoughnessFactor);
 1382|      0|                ReadTextureProperty(r, *curMaterialClearcoat, "clearcoatRoughnessTexture", clearcoat.clearcoatRoughnessTexture);
 1383|      0|                ReadTextureProperty(r, *curMaterialClearcoat, "clearcoatNormalTexture", clearcoat.clearcoatNormalTexture);
 1384|       |
 1385|      0|                this->materialClearcoat = Nullable<MaterialClearcoat>(clearcoat);
 1386|      0|            }
 1387|      0|        }
 1388|       |
 1389|      0|        if (r.extensionsUsed.KHR_materials_transmission) {
  ------------------
  |  Branch (1389:13): [True: 0, False: 0]
  ------------------
 1390|      0|            if (Value *curMaterialTransmission = FindObject(*extensions, "KHR_materials_transmission")) {
  ------------------
  |  Branch (1390:24): [True: 0, False: 0]
  ------------------
 1391|      0|                MaterialTransmission transmission;
 1392|       |
 1393|      0|                ReadMember(*curMaterialTransmission, "transmissionFactor", transmission.transmissionFactor);
 1394|      0|                ReadTextureProperty(r, *curMaterialTransmission, "transmissionTexture", transmission.transmissionTexture);
 1395|       |
 1396|      0|                this->materialTransmission = Nullable<MaterialTransmission>(transmission);
 1397|      0|            }
 1398|      0|        }
 1399|       |
 1400|      0|        if (r.extensionsUsed.KHR_materials_volume) {
  ------------------
  |  Branch (1400:13): [True: 0, False: 0]
  ------------------
 1401|      0|            if (Value *curMaterialVolume = FindObject(*extensions, "KHR_materials_volume")) {
  ------------------
  |  Branch (1401:24): [True: 0, False: 0]
  ------------------
 1402|      0|                MaterialVolume volume;
 1403|       |
 1404|      0|                ReadMember(*curMaterialVolume, "thicknessFactor", volume.thicknessFactor);
 1405|      0|                ReadTextureProperty(r, *curMaterialVolume, "thicknessTexture", volume.thicknessTexture);
 1406|      0|                ReadMember(*curMaterialVolume, "attenuationDistance", volume.attenuationDistance);
 1407|      0|                ReadMember(*curMaterialVolume, "attenuationColor", volume.attenuationColor);
 1408|       |
 1409|      0|                this->materialVolume = Nullable<MaterialVolume>(volume);
 1410|      0|            }
 1411|      0|        }
 1412|       |
 1413|      0|        if (r.extensionsUsed.KHR_materials_ior) {
  ------------------
  |  Branch (1413:13): [True: 0, False: 0]
  ------------------
 1414|      0|            if (Value *curMaterialIOR = FindObject(*extensions, "KHR_materials_ior")) {
  ------------------
  |  Branch (1414:24): [True: 0, False: 0]
  ------------------
 1415|      0|                MaterialIOR ior;
 1416|       |
 1417|      0|                ReadMember(*curMaterialIOR, "ior", ior.ior);
 1418|       |
 1419|      0|                this->materialIOR = Nullable<MaterialIOR>(ior);
 1420|      0|            }
 1421|      0|        }
 1422|       |
 1423|      0|        if (r.extensionsUsed.KHR_materials_emissive_strength) {
  ------------------
  |  Branch (1423:13): [True: 0, False: 0]
  ------------------
 1424|      0|            if (Value *curMaterialEmissiveStrength = FindObject(*extensions, "KHR_materials_emissive_strength")) {
  ------------------
  |  Branch (1424:24): [True: 0, False: 0]
  ------------------
 1425|      0|                MaterialEmissiveStrength emissiveStrength;
 1426|       |
 1427|      0|                ReadMember(*curMaterialEmissiveStrength, "emissiveStrength", emissiveStrength.emissiveStrength);
 1428|       |
 1429|      0|                this->materialEmissiveStrength = Nullable<MaterialEmissiveStrength>(emissiveStrength);
 1430|      0|            }
 1431|      0|        }
 1432|       |
 1433|      0|        if (r.extensionsUsed.KHR_materials_anisotropy) {
  ------------------
  |  Branch (1433:13): [True: 0, False: 0]
  ------------------
 1434|      0|            if (Value *curMaterialAnisotropy = FindObject(*extensions, "KHR_materials_anisotropy")) {
  ------------------
  |  Branch (1434:24): [True: 0, False: 0]
  ------------------
 1435|      0|                MaterialAnisotropy anisotropy;
 1436|       |
 1437|      0|                ReadMember(*curMaterialAnisotropy, "anisotropyStrength", anisotropy.anisotropyStrength);
 1438|      0|                ReadMember(*curMaterialAnisotropy, "anisotropyRotation", anisotropy.anisotropyRotation);
 1439|      0|                ReadTextureProperty(r, *curMaterialAnisotropy, "anisotropyTexture", anisotropy.anisotropyTexture);
 1440|       |
 1441|      0|                this->materialAnisotropy = Nullable<MaterialAnisotropy>(anisotropy);
 1442|      0|            }
 1443|      0|        }
 1444|       |
 1445|      0|        unlit = nullptr != FindObject(*extensions, "KHR_materials_unlit");
 1446|      0|    }
 1447|  1.54k|}
_ZN5glTF28Material11SetDefaultsEv:
 1449|  5.08k|inline void Material::SetDefaults() {
 1450|       |    //pbr materials
 1451|  5.08k|    SetVector(pbrMetallicRoughness.baseColorFactor, defaultBaseColor);
 1452|  5.08k|    pbrMetallicRoughness.metallicFactor = 1.0f;
 1453|  5.08k|    pbrMetallicRoughness.roughnessFactor = 1.0f;
 1454|       |
 1455|  5.08k|    SetVector(emissiveFactor, defaultEmissiveFactor);
 1456|  5.08k|    alphaMode = "OPAQUE";
 1457|  5.08k|    alphaCutoff = 0.5f;
 1458|  5.08k|    doubleSided = false;
 1459|  5.08k|    unlit = false;
 1460|  5.08k|}
_ZN5glTF221PbrSpecularGlossiness11SetDefaultsEv:
 1462|  3.54k|inline void PbrSpecularGlossiness::SetDefaults() {
 1463|       |    //pbrSpecularGlossiness properties
 1464|  3.54k|    SetVector(diffuseFactor, defaultDiffuseFactor);
 1465|  3.54k|    SetVector(specularFactor, defaultSpecularFactor);
 1466|  3.54k|    glossinessFactor = 1.0f;
 1467|  3.54k|}
_ZN5glTF216MaterialSpecular11SetDefaultsEv:
 1469|  3.54k|inline void MaterialSpecular::SetDefaults() {
 1470|       |    //KHR_materials_specular properties
 1471|  3.54k|    SetVector(specularColorFactor, defaultSpecularColorFactor);
 1472|  3.54k|    specularFactor = 1.f;
 1473|  3.54k|}
_ZN5glTF213MaterialSheen11SetDefaultsEv:
 1475|  3.54k|inline void MaterialSheen::SetDefaults() {
 1476|       |    //KHR_materials_sheen properties
 1477|  3.54k|    SetVector(sheenColorFactor, defaultSheenFactor);
 1478|  3.54k|    sheenRoughnessFactor = 0.f;
 1479|  3.54k|}
_ZN5glTF214MaterialVolume11SetDefaultsEv:
 1481|  3.54k|inline void MaterialVolume::SetDefaults() {
 1482|       |    //KHR_materials_volume properties
 1483|  3.54k|    thicknessFactor = 0.f;
 1484|  3.54k|    attenuationDistance = std::numeric_limits<float>::infinity();
 1485|  3.54k|    SetVector(attenuationColor, defaultAttenuationColor);
 1486|  3.54k|}
_ZN5glTF211MaterialIOR11SetDefaultsEv:
 1488|  3.54k|inline void MaterialIOR::SetDefaults() {
 1489|       |    //KHR_materials_ior properties
 1490|  3.54k|    ior = 1.5f;
 1491|  3.54k|}
_ZN5glTF224MaterialEmissiveStrength11SetDefaultsEv:
 1493|  3.54k|inline void MaterialEmissiveStrength::SetDefaults() {
 1494|       |    //KHR_materials_emissive_strength properties
 1495|  3.54k|    emissiveStrength = 0.f;
 1496|  3.54k|}
_ZN5glTF218MaterialAnisotropy11SetDefaultsEv:
 1498|  3.54k|inline void MaterialAnisotropy::SetDefaults() {
 1499|       |    //KHR_materials_anisotropy properties
 1500|  3.54k|    anisotropyStrength = 0.f;
 1501|  3.54k|    anisotropyRotation = 0.f;
 1502|  3.54k|}
_ZN5glTF24Mesh4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
 1504|  1.95k|inline void Mesh::Read(Value &pJSON_Object, Asset &pAsset_Root) {
 1505|  1.95k|    Value *curName = FindMember(pJSON_Object, "name");
 1506|  1.95k|    if (nullptr != curName && curName->IsString()) {
  ------------------
  |  Branch (1506:9): [True: 1.51k, False: 434]
  |  Branch (1506:31): [True: 1.51k, False: 1]
  ------------------
 1507|  1.51k|        name = curName->GetString();
 1508|  1.51k|    }
 1509|       |
 1510|       |    /****************** Mesh primitives ******************/
 1511|  1.95k|    Value *curPrimitives = FindArray(pJSON_Object, "primitives");
 1512|  1.95k|    if (nullptr != curPrimitives) {
  ------------------
  |  Branch (1512:9): [True: 1.91k, False: 37]
  ------------------
 1513|  1.91k|        this->primitives.resize(curPrimitives->Size());
 1514|  3.83k|        for (unsigned int i = 0; i < curPrimitives->Size(); ++i) {
  ------------------
  |  Branch (1514:34): [True: 1.94k, False: 1.89k]
  ------------------
 1515|  1.94k|            Value &primitive = (*curPrimitives)[i];
 1516|       |
 1517|  1.94k|            Primitive &prim = this->primitives[i];
 1518|  1.94k|            prim.mode = MemberOrDefault(primitive, "mode", PrimitiveMode_TRIANGLES);
 1519|       |
 1520|  1.94k|            if (Value *indices = FindUInt(primitive, "indices")) {
  ------------------
  |  Branch (1520:24): [True: 1.16k, False: 776]
  ------------------
 1521|  1.16k|                prim.indices = pAsset_Root.accessors.Retrieve(indices->GetUint());
 1522|  1.16k|            }
 1523|       |
 1524|  1.94k|            if (Value *material = FindUInt(primitive, "material")) {
  ------------------
  |  Branch (1524:24): [True: 1.54k, False: 395]
  ------------------
 1525|  1.54k|                prim.material = pAsset_Root.materials.Retrieve(material->GetUint());
 1526|  1.54k|            }
 1527|       |
 1528|  1.94k|            if (Value *attrs = FindObject(primitive, "attributes")) {
  ------------------
  |  Branch (1528:24): [True: 1.81k, False: 127]
  ------------------
 1529|  8.24k|                for (Value::MemberIterator it = attrs->MemberBegin(); it != attrs->MemberEnd(); ++it) {
  ------------------
  |  Branch (1529:71): [True: 6.45k, False: 1.79k]
  ------------------
 1530|  6.45k|                    if (!it->value.IsUint()) continue;
  ------------------
  |  Branch (1530:25): [True: 10, False: 6.44k]
  ------------------
 1531|  6.44k|                    const char *attr = it->name.GetString();
 1532|       |                    // Valid attribute semantics include POSITION, NORMAL, TANGENT, TEXCOORD, COLOR, JOINT, JOINTMATRIX,
 1533|       |                    // and WEIGHT.Attribute semantics can be of the form[semantic]_[set_index], e.g., TEXCOORD_0, TEXCOORD_1, etc.
 1534|       |
 1535|  6.44k|                    int undPos = 0;
 1536|  6.44k|                    Mesh::AccessorList *vec = nullptr;
 1537|  6.44k|                    if (GetAttribVector(prim, attr, vec, undPos)) {
  ------------------
  |  Branch (1537:25): [True: 5.89k, False: 551]
  ------------------
 1538|  5.89k|                        size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0;
  ------------------
  |  Branch (1538:38): [True: 2.71k, False: 3.18k]
  ------------------
 1539|  5.89k|                        if ((*vec).size() != idx) {
  ------------------
  |  Branch (1539:29): [True: 20, False: 5.87k]
  ------------------
 1540|     20|                            throw DeadlyImportError("GLTF: Invalid attribute in mesh: ", name, " primitive: ", i, "attrib: ", attr,
 1541|     20|                                    ". All indices for indexed attribute semantics must start with 0 and be continuous positive integers: TEXCOORD_0, TEXCOORD_1, etc.");
 1542|     20|                        }
 1543|  5.87k|                        (*vec).resize(idx + 1);
 1544|  5.87k|                        (*vec)[idx] = pAsset_Root.accessors.Retrieve(it->value.GetUint());
 1545|  5.87k|                    }
 1546|  6.44k|                }
 1547|  1.81k|            }
 1548|       |
 1549|       |#ifdef ASSIMP_ENABLE_DRACO
 1550|       |            // KHR_draco_mesh_compression spec: Draco can only be used for glTF Triangles or Triangle Strips
 1551|       |            if (pAsset_Root.extensionsUsed.KHR_draco_mesh_compression && (prim.mode == PrimitiveMode_TRIANGLES || prim.mode == PrimitiveMode_TRIANGLE_STRIP)) {
 1552|       |                // Look for draco mesh compression extension and bufferView
 1553|       |                // Skip if any missing
 1554|       |                if (Value *dracoExt = FindExtension(primitive, "KHR_draco_mesh_compression")) {
 1555|       |                    if (Value *bufView = FindUInt(*dracoExt, "bufferView")) {
 1556|       |                        // Attempt to load indices and attributes using draco compression
 1557|       |                        auto bufferView = pAsset_Root.bufferViews.Retrieve(bufView->GetUint());
 1558|       |                        // Attempt to perform the draco decode on the buffer data
 1559|       |                        const char *bufferViewData = reinterpret_cast<const char *>(bufferView->buffer->GetPointer() + bufferView->byteOffset);
 1560|       |                        draco::DecoderBuffer decoderBuffer;
 1561|       |                        decoderBuffer.Init(bufferViewData, bufferView->byteLength);
 1562|       |                        draco::Decoder decoder;
 1563|       |                        auto decodeResult = decoder.DecodeMeshFromBuffer(&decoderBuffer);
 1564|       |                        if (!decodeResult.ok()) {
 1565|       |                            // A corrupt Draco isn't actually fatal if the primitive data is also provided in a standard buffer, but does anyone do that?
 1566|       |                            throw DeadlyImportError("GLTF: Invalid Draco mesh compression in mesh: ", name, " primitive: ", i, ": ", decodeResult.status().error_msg_string());
 1567|       |                        }
 1568|       |
 1569|       |                        // Now we have a draco mesh
 1570|       |                        const std::unique_ptr<draco::Mesh> &pDracoMesh = decodeResult.value();
 1571|       |
 1572|       |                        // Redirect the accessors to the decoded data
 1573|       |
 1574|       |                        // Indices
 1575|       |                        SetDecodedIndexBuffer_Draco(*pDracoMesh, prim);
 1576|       |
 1577|       |                        // Vertex attributes
 1578|       |                        if (Value *attrs = FindObject(*dracoExt, "attributes")) {
 1579|       |                            for (Value::MemberIterator it = attrs->MemberBegin(); it != attrs->MemberEnd(); ++it) {
 1580|       |                                if (!it->value.IsUint()) continue;
 1581|       |                                const char *attr = it->name.GetString();
 1582|       |
 1583|       |                                int undPos = 0;
 1584|       |                                Mesh::AccessorList *vec = nullptr;
 1585|       |                                if (GetAttribVector(prim, attr, vec, undPos)) {
 1586|       |                                    size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0;
 1587|       |                                    if (idx >= (*vec).size()) {
 1588|       |                                        throw DeadlyImportError("GLTF: Invalid draco attribute in mesh: ", name, " primitive: ", i, " attrib: ", attr,
 1589|       |                                                ". All indices for indexed attribute semantics must start with 0 and be continuous positive integers: TEXCOORD_0, TEXCOORD_1, etc.");
 1590|       |                                    }
 1591|       |
 1592|       |                                    if (!(*vec)[idx]) {
 1593|       |                                        throw DeadlyImportError("GLTF: Invalid draco attribute in mesh: ", name, " primitive: ", i, " attrib: ", attr,
 1594|       |                                                ". All draco-encoded attributes must also define an accessor.");
 1595|       |                                    }
 1596|       |
 1597|       |                                    Accessor &attribAccessor = *(*vec)[idx];
 1598|       |                                    if (attribAccessor.count == 0)
 1599|       |                                        throw DeadlyImportError("GLTF: Invalid draco attribute in mesh: ", name, " primitive: ", i, " attrib: ", attr);
 1600|       |
 1601|       |                                    // Redirect this accessor to the appropriate Draco vertex attribute data
 1602|       |                                    const uint32_t dracoAttribId = it->value.GetUint();
 1603|       |                                    SetDecodedAttributeBuffer_Draco(*pDracoMesh, dracoAttribId, attribAccessor);
 1604|       |                                }
 1605|       |                            }
 1606|       |                        }
 1607|       |                    }
 1608|       |                }
 1609|       |            }
 1610|       |#endif
 1611|       |
 1612|  1.92k|            Value *targetsArray = FindArray(primitive, "targets");
 1613|  1.92k|            if (nullptr != targetsArray) {
  ------------------
  |  Branch (1613:17): [True: 0, False: 1.92k]
  ------------------
 1614|      0|                prim.targets.resize(targetsArray->Size());
 1615|      0|                for (unsigned int j = 0; j < targetsArray->Size(); ++j) {
  ------------------
  |  Branch (1615:42): [True: 0, False: 0]
  ------------------
 1616|      0|                    Value &target = (*targetsArray)[j];
 1617|      0|                    if (!target.IsObject()) {
  ------------------
  |  Branch (1617:25): [True: 0, False: 0]
  ------------------
 1618|      0|                        continue;
 1619|      0|                    }
 1620|      0|                    for (Value::MemberIterator it = target.MemberBegin(); it != target.MemberEnd(); ++it) {
  ------------------
  |  Branch (1620:75): [True: 0, False: 0]
  ------------------
 1621|      0|                        if (!it->value.IsUint()) {
  ------------------
  |  Branch (1621:29): [True: 0, False: 0]
  ------------------
 1622|      0|                            continue;
 1623|      0|                        }
 1624|      0|                        const char *attr = it->name.GetString();
 1625|       |                        // Valid attribute semantics include POSITION, NORMAL, TANGENT
 1626|      0|                        int undPos = 0;
 1627|      0|                        Mesh::AccessorList *vec = nullptr;
 1628|      0|                        if (GetAttribTargetVector(prim, j, attr, vec, undPos)) {
  ------------------
  |  Branch (1628:29): [True: 0, False: 0]
  ------------------
 1629|      0|                            size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0;
  ------------------
  |  Branch (1629:42): [True: 0, False: 0]
  ------------------
 1630|      0|                            if ((*vec).size() <= idx) {
  ------------------
  |  Branch (1630:33): [True: 0, False: 0]
  ------------------
 1631|      0|                                (*vec).resize(idx + 1);
 1632|      0|                            }
 1633|      0|                            (*vec)[idx] = pAsset_Root.accessors.Retrieve(it->value.GetUint());
 1634|      0|                        }
 1635|      0|                    }
 1636|      0|                }
 1637|      0|            }
 1638|       |
 1639|  1.92k|            if(this->targetNames.empty())
  ------------------
  |  Branch (1639:16): [True: 1.77k, False: 150]
  ------------------
 1640|  1.77k|            {
 1641|  1.77k|                Value *curExtras = FindObject(primitive, "extras");
 1642|  1.77k|                if (nullptr != curExtras) {
  ------------------
  |  Branch (1642:21): [True: 1, False: 1.77k]
  ------------------
 1643|      1|                    if (Value *curTargetNames = FindArray(*curExtras, "targetNames")) {
  ------------------
  |  Branch (1643:32): [True: 0, False: 1]
  ------------------
 1644|      0|                        this->targetNames.resize(curTargetNames->Size());
 1645|      0|                        for (unsigned int j = 0; j < curTargetNames->Size(); ++j) {
  ------------------
  |  Branch (1645:50): [True: 0, False: 0]
  ------------------
 1646|      0|                            Value &targetNameValue = (*curTargetNames)[j];
 1647|      0|                            if (targetNameValue.IsString()) {
  ------------------
  |  Branch (1647:33): [True: 0, False: 0]
  ------------------
 1648|      0|                                this->targetNames[j] = targetNameValue.GetString();
 1649|      0|                            }
 1650|      0|                        }
 1651|      0|                    }
 1652|      1|                }
 1653|  1.77k|            }
 1654|  1.92k|        }
 1655|  1.91k|    }
 1656|       |
 1657|  1.93k|    Value *curWeights = FindArray(pJSON_Object, "weights");
 1658|  1.93k|    if (nullptr != curWeights) {
  ------------------
  |  Branch (1658:9): [True: 0, False: 1.93k]
  ------------------
 1659|      0|        this->weights.resize(curWeights->Size());
 1660|      0|        for (unsigned int i = 0; i < curWeights->Size(); ++i) {
  ------------------
  |  Branch (1660:34): [True: 0, False: 0]
  ------------------
 1661|      0|            Value &weightValue = (*curWeights)[i];
 1662|      0|            if (weightValue.IsNumber()) {
  ------------------
  |  Branch (1662:17): [True: 0, False: 0]
  ------------------
 1663|      0|                this->weights[i] = weightValue.GetFloat();
 1664|      0|            }
 1665|      0|        }
 1666|      0|    }
 1667|       |
 1668|  1.93k|    Value *curExtras = FindObject(pJSON_Object, "extras");
 1669|  1.93k|    if (nullptr != curExtras) {
  ------------------
  |  Branch (1669:9): [True: 0, False: 1.93k]
  ------------------
 1670|      0|        if (Value *curTargetNames = FindArray(*curExtras, "targetNames")) {
  ------------------
  |  Branch (1670:20): [True: 0, False: 0]
  ------------------
 1671|      0|            this->targetNames.resize(curTargetNames->Size());
 1672|      0|            for (unsigned int i = 0; i < curTargetNames->Size(); ++i) {
  ------------------
  |  Branch (1672:38): [True: 0, False: 0]
  ------------------
 1673|      0|                Value &targetNameValue = (*curTargetNames)[i];
 1674|      0|                if (targetNameValue.IsString()) {
  ------------------
  |  Branch (1674:21): [True: 0, False: 0]
  ------------------
 1675|      0|                    this->targetNames[i] = targetNameValue.GetString();
 1676|      0|                }
 1677|      0|            }
 1678|      0|        }
 1679|      0|    }
 1680|  1.93k|}
_ZN5glTF24Node4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
 1739|  11.5k|inline void Node::Read(Value &obj, Asset &r) {
 1740|  11.5k|    if (name.empty()) {
  ------------------
  |  Branch (1740:9): [True: 1.14k, False: 10.4k]
  ------------------
 1741|  1.14k|        name = id;
 1742|  1.14k|    }
 1743|       |
 1744|  11.5k|    Value *curChildren = FindArray(obj, "children");
 1745|  11.5k|    if (nullptr != curChildren) {
  ------------------
  |  Branch (1745:9): [True: 5.69k, False: 5.85k]
  ------------------
 1746|  5.69k|        this->children.reserve(curChildren->Size());
 1747|  14.4k|        for (unsigned int i = 0; i < curChildren->Size(); ++i) {
  ------------------
  |  Branch (1747:34): [True: 8.76k, False: 5.69k]
  ------------------
 1748|  8.76k|            Value &child = (*curChildren)[i];
 1749|  8.76k|            if (child.IsUint()) {
  ------------------
  |  Branch (1749:17): [True: 8.70k, False: 53]
  ------------------
 1750|       |                // get/create the child node
 1751|  8.70k|                Ref<Node> chn = r.nodes.Retrieve(child.GetUint());
 1752|  8.70k|                if (chn) {
  ------------------
  |  Branch (1752:21): [True: 8.42k, False: 288]
  ------------------
 1753|  8.42k|                    this->children.push_back(chn);
 1754|  8.42k|                }
 1755|  8.70k|            }
 1756|  8.76k|        }
 1757|  5.69k|    }
 1758|       |
 1759|  11.5k|    Value *curMatrix = FindArray(obj, "matrix");
 1760|  11.5k|    if (nullptr != curMatrix) {
  ------------------
  |  Branch (1760:9): [True: 9.12k, False: 2.42k]
  ------------------
 1761|  9.12k|        ReadValue(*curMatrix, this->matrix);
 1762|  9.12k|    } else {
 1763|  2.42k|        ReadMember(obj, "translation", translation);
 1764|  2.42k|        ReadMember(obj, "scale", scale);
 1765|  2.42k|        ReadMember(obj, "rotation", rotation);
 1766|  2.42k|    }
 1767|       |
 1768|  11.5k|    Value *curMesh = FindUInt(obj, "mesh");
 1769|  11.5k|    if (nullptr != curMesh) {
  ------------------
  |  Branch (1769:9): [True: 1.96k, False: 9.58k]
  ------------------
 1770|  1.96k|        unsigned int numMeshes = 1;
 1771|  1.96k|        this->meshes.reserve(numMeshes);
 1772|  1.96k|        Ref<Mesh> meshRef = r.meshes.Retrieve((*curMesh).GetUint());
 1773|  1.96k|        if (meshRef) {
  ------------------
  |  Branch (1773:13): [True: 1.78k, False: 187]
  ------------------
 1774|  1.78k|            this->meshes.push_back(meshRef);
 1775|  1.78k|        }
 1776|  1.96k|    }
 1777|       |
 1778|       |    // Do not retrieve a skin here, just take a reference, to avoid infinite recursion
 1779|       |    // Skins will be properly loaded later
 1780|  11.5k|    Value *curSkin = FindUInt(obj, "skin");
 1781|  11.5k|    if (nullptr != curSkin) {
  ------------------
  |  Branch (1781:9): [True: 320, False: 11.2k]
  ------------------
 1782|    320|        this->skin = r.skins.Get(curSkin->GetUint());
 1783|    320|    }
 1784|       |
 1785|  11.5k|    Value *curCamera = FindUInt(obj, "camera");
 1786|  11.5k|    if (nullptr != curCamera) {
  ------------------
  |  Branch (1786:9): [True: 0, False: 11.5k]
  ------------------
 1787|      0|        this->camera = r.cameras.Retrieve(curCamera->GetUint());
 1788|      0|        if (this->camera) {
  ------------------
  |  Branch (1788:13): [True: 0, False: 0]
  ------------------
 1789|      0|            this->camera->id = this->id;
 1790|      0|        }
 1791|      0|    }
 1792|       |
 1793|  11.5k|    Value *curExtensions = FindObject(obj, "extensions");
 1794|  11.5k|    if (nullptr != curExtensions) {
  ------------------
  |  Branch (1794:9): [True: 0, False: 11.5k]
  ------------------
 1795|      0|        if (r.extensionsUsed.KHR_lights_punctual) {
  ------------------
  |  Branch (1795:13): [True: 0, False: 0]
  ------------------
 1796|      0|            if (Value *ext = FindObject(*curExtensions, "KHR_lights_punctual")) {
  ------------------
  |  Branch (1796:24): [True: 0, False: 0]
  ------------------
 1797|      0|                Value *curLight = FindUInt(*ext, "light");
 1798|      0|                if (nullptr != curLight) {
  ------------------
  |  Branch (1798:21): [True: 0, False: 0]
  ------------------
 1799|      0|                    this->light = r.lights.Retrieve(curLight->GetUint());
 1800|      0|                    if (this->light) {
  ------------------
  |  Branch (1800:25): [True: 0, False: 0]
  ------------------
 1801|      0|                        this->light->id = this->id;
 1802|      0|                    }
 1803|      0|                }
 1804|      0|            }
 1805|      0|        }
 1806|      0|    }
 1807|  11.5k|}
_ZN5glTF25Scene4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
 1809|  2.16k|inline void Scene::Read(Value &obj, Asset &r) {
 1810|  2.16k|    if (Value *scene_name = FindString(obj, "name")) {
  ------------------
  |  Branch (1810:16): [True: 6, False: 2.15k]
  ------------------
 1811|      6|        if (scene_name->IsString()) {
  ------------------
  |  Branch (1811:13): [True: 6, False: 0]
  ------------------
 1812|      6|            this->name = scene_name->GetString();
 1813|      6|        }
 1814|      6|    }
 1815|  2.16k|    if (Value *array = FindArray(obj, "nodes")) {
  ------------------
  |  Branch (1815:16): [True: 2.12k, False: 33]
  ------------------
 1816|  5.04k|        for (unsigned int i = 0; i < array->Size(); ++i) {
  ------------------
  |  Branch (1816:34): [True: 2.91k, False: 2.12k]
  ------------------
 1817|  2.91k|            if (!(*array)[i].IsUint()) continue;
  ------------------
  |  Branch (1817:17): [True: 54, False: 2.86k]
  ------------------
 1818|  2.86k|            Ref<Node> node = r.nodes.Retrieve((*array)[i].GetUint());
 1819|  2.86k|            if (node)
  ------------------
  |  Branch (1819:17): [True: 2.61k, False: 250]
  ------------------
 1820|  2.61k|                this->nodes.push_back(node);
 1821|  2.86k|        }
 1822|  2.12k|    }
 1823|  2.16k|}
_ZN5glTF24Skin4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
 1825|    369|inline void Skin::Read(Value &obj, Asset &r) {
 1826|    369|    if (Value *matrices = FindUInt(obj, "inverseBindMatrices")) {
  ------------------
  |  Branch (1826:16): [True: 340, False: 29]
  ------------------
 1827|    340|        inverseBindMatrices = r.accessors.Retrieve(matrices->GetUint());
 1828|    340|    }
 1829|       |
 1830|    369|    if (Value *joints = FindArray(obj, "joints")) {
  ------------------
  |  Branch (1830:16): [True: 330, False: 39]
  ------------------
 1831|  3.52k|        for (unsigned i = 0; i < joints->Size(); ++i) {
  ------------------
  |  Branch (1831:30): [True: 3.19k, False: 330]
  ------------------
 1832|  3.19k|            if (!(*joints)[i].IsUint()) continue;
  ------------------
  |  Branch (1832:17): [True: 32, False: 3.16k]
  ------------------
 1833|  3.16k|            Ref<Node> node = r.nodes.Retrieve((*joints)[i].GetUint());
 1834|  3.16k|            if (node) {
  ------------------
  |  Branch (1834:17): [True: 3.14k, False: 17]
  ------------------
 1835|  3.14k|                this->jointNames.push_back(node);
 1836|  3.14k|            }
 1837|  3.16k|        }
 1838|    330|    }
 1839|    369|}
_ZN5glTF213AssetMetadata4ReadERN9rapidjson15GenericDocumentINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEES6_EE:
 1902|  4.93k|inline void AssetMetadata::Read(Document &doc) {
 1903|  4.93k|    if (Value *obj = FindObject(doc, "asset")) {
  ------------------
  |  Branch (1903:16): [True: 4.48k, False: 446]
  ------------------
 1904|  4.48k|        ReadMember(*obj, "copyright", copyright);
 1905|  4.48k|        ReadMember(*obj, "generator", generator);
 1906|       |
 1907|  4.48k|        if (Value *versionString = FindStringInContext(*obj, "version", "\"asset\"")) {
  ------------------
  |  Branch (1907:20): [True: 4.04k, False: 447]
  ------------------
 1908|  4.04k|            version = versionString->GetString();
 1909|  4.04k|        }
 1910|  4.48k|        Value *curProfile = FindObjectInContext(*obj, "profile", "\"asset\"");
 1911|  4.48k|        if (nullptr != curProfile) {
  ------------------
  |  Branch (1911:13): [True: 0, False: 4.48k]
  ------------------
 1912|      0|            ReadMember(*curProfile, "api", this->profile.api);
 1913|      0|            ReadMember(*curProfile, "version", this->profile.version);
 1914|      0|        }
 1915|  4.48k|    }
 1916|       |
 1917|  4.93k|    if (version.empty() || version[0] != '2') {
  ------------------
  |  Branch (1917:9): [True: 170, False: 4.76k]
  |  Branch (1917:28): [True: 54, False: 4.71k]
  ------------------
 1918|    216|        throw DeadlyImportError("GLTF: Unsupported glTF version: ", version);
 1919|    216|    }
 1920|  4.93k|}
_ZN5glTF25Asset16ReadBinaryHeaderERN6Assimp8IOStreamERNSt3__16vectorIcNS4_9allocatorIcEEEE:
 1926|  4.48k|inline void Asset::ReadBinaryHeader(IOStream &stream, std::vector<char> &sceneData) {
 1927|  4.48k|    ASSIMP_LOG_DEBUG("Reading GLTF2 binary");
 1928|  4.48k|    GLB_Header header;
 1929|  4.48k|    if (stream.Read(&header, sizeof(header), 1) != 1) {
  ------------------
  |  Branch (1929:9): [True: 0, False: 4.48k]
  ------------------
 1930|      0|        throw DeadlyImportError("GLTF: Unable to read the file header");
 1931|      0|    }
 1932|       |
 1933|  4.48k|    if (strncmp((char *)header.magic, AI_GLB_MAGIC_NUMBER, sizeof(header.magic)) != 0) {
  ------------------
  |  |  147|  4.48k|#define AI_GLB_MAGIC_NUMBER "glTF"
  ------------------
  |  Branch (1933:9): [True: 0, False: 4.48k]
  ------------------
 1934|      0|        throw DeadlyImportError("GLTF: Invalid binary glTF file");
 1935|      0|    }
 1936|       |
 1937|  4.48k|    AI_SWAP4(header.version);
 1938|  4.48k|    asset.version = ai_to_string(header.version);
 1939|  4.48k|    if (header.version != 2) {
  ------------------
  |  Branch (1939:9): [True: 162, False: 4.32k]
  ------------------
 1940|    162|        throw DeadlyImportError("GLTF: Unsupported binary glTF version");
 1941|    162|    }
 1942|       |
 1943|  4.32k|    GLB_Chunk chunk;
 1944|  4.32k|    if (stream.Read(&chunk, sizeof(chunk), 1) != 1) {
  ------------------
  |  Branch (1944:9): [True: 0, False: 4.32k]
  ------------------
 1945|      0|        throw DeadlyImportError("GLTF: Unable to read JSON chunk");
 1946|      0|    }
 1947|       |
 1948|  4.32k|    AI_SWAP4(chunk.chunkLength);
 1949|  4.32k|    AI_SWAP4(chunk.chunkType);
 1950|       |
 1951|  4.32k|    if (chunk.chunkType != ChunkType_JSON) {
  ------------------
  |  Branch (1951:9): [True: 10, False: 4.31k]
  ------------------
 1952|     10|        throw DeadlyImportError("GLTF: JSON chunk missing");
 1953|     10|    }
 1954|       |
 1955|       |    // read the scene data, ensure null termination
 1956|  4.31k|    static_assert(std::numeric_limits<uint32_t>::max() <= std::numeric_limits<size_t>::max(), "size_t must be at least 32bits");
 1957|  4.31k|    mSceneLength = chunk.chunkLength; // Can't be larger than 4GB (max. uint32_t)
 1958|  4.31k|    sceneData.resize(mSceneLength + 1);
 1959|  4.31k|    sceneData[mSceneLength] = '\0';
 1960|       |
 1961|  4.31k|    if (stream.Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
  ------------------
  |  Branch (1961:9): [True: 28, False: 4.28k]
  ------------------
 1962|     28|        throw DeadlyImportError("GLTF: Could not read the file contents");
 1963|     28|    }
 1964|       |
 1965|  4.28k|    uint32_t padding = ((chunk.chunkLength + 3) & ~3) - chunk.chunkLength;
 1966|  4.28k|    if (padding > 0) {
  ------------------
  |  Branch (1966:9): [True: 66, False: 4.22k]
  ------------------
 1967|     66|        stream.Seek(padding, aiOrigin_CUR);
 1968|     66|    }
 1969|       |
 1970|  4.28k|    AI_SWAP4(header.length);
 1971|  4.28k|    mBodyOffset = 12 + 8 + chunk.chunkLength + padding + 8;
 1972|  4.28k|    if (header.length >= mBodyOffset) {
  ------------------
  |  Branch (1972:9): [True: 4.22k, False: 64]
  ------------------
 1973|  4.22k|        if (stream.Read(&chunk, sizeof(chunk), 1) != 1) {
  ------------------
  |  Branch (1973:13): [True: 28, False: 4.19k]
  ------------------
 1974|     28|            throw DeadlyImportError("GLTF: Unable to read BIN chunk");
 1975|     28|        }
 1976|       |
 1977|  4.19k|        AI_SWAP4(chunk.chunkLength);
 1978|  4.19k|        AI_SWAP4(chunk.chunkType);
 1979|       |
 1980|  4.19k|        if (chunk.chunkType != ChunkType_BIN) {
  ------------------
  |  Branch (1980:13): [True: 130, False: 4.06k]
  ------------------
 1981|    130|            throw DeadlyImportError("GLTF: BIN chunk missing");
 1982|    130|        }
 1983|       |
 1984|  4.06k|        mBodyLength = chunk.chunkLength;
 1985|  4.06k|    } else {
 1986|     64|        mBodyOffset = mBodyLength = 0;
 1987|     64|    }
 1988|  4.28k|}
_ZN5glTF25Asset12ReadDocumentERN6Assimp8IOStreamEbRNSt3__16vectorIcNS4_9allocatorIcEEEE:
 1990|  6.79k|inline rapidjson::Document Asset::ReadDocument(IOStream &stream, bool isBinary, std::vector<char> &sceneData) {
 1991|  6.79k|    ASSIMP_LOG_DEBUG("Loading GLTF2 asset");
 1992|       |
 1993|       |    // is binary? then read the header
 1994|  6.79k|    if (isBinary) {
  ------------------
  |  Branch (1994:9): [True: 4.48k, False: 2.31k]
  ------------------
 1995|  4.48k|        SetAsBinary(); // also creates the body buffer
 1996|  4.48k|        ReadBinaryHeader(stream, sceneData);
 1997|  4.48k|    } else {
 1998|  2.31k|        mSceneLength = stream.FileSize();
 1999|  2.31k|        mBodyLength = 0;
 2000|       |
 2001|       |        // Binary format only supports up to 4GB of JSON, use that as a maximum
 2002|  2.31k|        if (mSceneLength >= std::numeric_limits<uint32_t>::max()) {
  ------------------
  |  Branch (2002:13): [True: 0, False: 2.31k]
  ------------------
 2003|      0|            throw DeadlyImportError("GLTF: JSON size greater than 4GB");
 2004|      0|        }
 2005|       |
 2006|       |        // read the scene data, ensure null termination
 2007|  2.31k|        sceneData.resize(mSceneLength + 1);
 2008|  2.31k|        sceneData[mSceneLength] = '\0';
 2009|       |
 2010|  2.31k|        if (stream.Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
  ------------------
  |  Branch (2010:13): [True: 0, False: 2.31k]
  ------------------
 2011|      0|            throw DeadlyImportError("GLTF: Could not read the file contents");
 2012|      0|        }
 2013|  2.31k|    }
 2014|       |
 2015|       |    // Smallest legal JSON file is "{}" Smallest loadable glTF file is larger than that but catch it later
 2016|  6.79k|    if (mSceneLength < 2) {
  ------------------
  |  Branch (2016:9): [True: 0, False: 6.79k]
  ------------------
 2017|      0|        throw DeadlyImportError("GLTF: No JSON file contents");
 2018|      0|    }
 2019|       |
 2020|       |    // parse the JSON document
 2021|  6.79k|    ASSIMP_LOG_DEBUG("Parsing GLTF2 JSON");
 2022|  6.79k|    Document doc;
 2023|  6.79k|    doc.ParseInsitu(&sceneData[0]);
 2024|       |
 2025|  6.79k|    if (doc.HasParseError()) {
  ------------------
  |  Branch (2025:9): [True: 1.36k, False: 5.43k]
  ------------------
 2026|  1.36k|        char buffer[32];
 2027|  1.36k|        ai_snprintf(buffer, 32, "%d", static_cast<int>(doc.GetErrorOffset()));
 2028|  1.36k|        throw DeadlyImportError("GLTF: JSON parse error, offset ", buffer, ": ", GetParseError_En(doc.GetParseError()));
 2029|  1.36k|    }
 2030|       |
 2031|  5.43k|    if (!doc.IsObject()) {
  ------------------
  |  Branch (2031:9): [True: 72, False: 5.36k]
  ------------------
 2032|     72|        throw DeadlyImportError("GLTF: JSON document root must be a JSON object");
 2033|     72|    }
 2034|       |
 2035|  5.36k|    return doc;
 2036|  5.43k|}
_ZN5glTF25Asset4LoadERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEb:
 2039|  2.39k|{
 2040|  2.39k|    mCurrentAssetDir.clear();
 2041|  2.39k|    if (0 != strncmp(pFile.c_str(), AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH)) {
  ------------------
  |  Branch (2041:9): [True: 0, False: 2.39k]
  ------------------
 2042|      0|        mCurrentAssetDir = glTFCommon::getCurrentAssetDir(pFile);
 2043|      0|    }
 2044|       |
 2045|  2.39k|    shared_ptr<IOStream> stream(OpenFile(pFile.c_str(), "rb", true));
 2046|  2.39k|    if (!stream) {
  ------------------
  |  Branch (2046:9): [True: 0, False: 2.39k]
  ------------------
 2047|      0|        throw DeadlyImportError("GLTF: Could not open file for reading");
 2048|      0|    }
 2049|       |
 2050|  2.39k|    std::vector<char> sceneData;
 2051|  2.39k|    rapidjson::Document doc = ReadDocument(*stream, isBinary, sceneData);
 2052|       |
 2053|       |    // If a schemaDocumentProvider is available, see if the glTF schema is present.
 2054|       |    // If so, use it to validate the document.
 2055|  2.39k|    if (mSchemaDocumentProvider) {
  ------------------
  |  Branch (2055:9): [True: 0, False: 2.39k]
  ------------------
 2056|      0|        if (const rapidjson::SchemaDocument *gltfSchema = mSchemaDocumentProvider->GetRemoteDocument("glTF.schema.json", 16)) {
  ------------------
  |  Branch (2056:46): [True: 0, False: 0]
  ------------------
 2057|       |            // The schemas are found here: https://github.com/KhronosGroup/glTF/tree/main/specification/2.0/schema
 2058|      0|            rapidjson::SchemaValidator validator(*gltfSchema);
 2059|      0|            if (!doc.Accept(validator)) {
  ------------------
  |  Branch (2059:17): [True: 0, False: 0]
  ------------------
 2060|      0|                rapidjson::StringBuffer pathBuffer;
 2061|      0|                validator.GetInvalidSchemaPointer().StringifyUriFragment(pathBuffer);
 2062|      0|                rapidjson::StringBuffer argumentBuffer;
 2063|      0|                validator.GetInvalidDocumentPointer().StringifyUriFragment(argumentBuffer);
 2064|      0|                throw DeadlyImportError("GLTF: The JSON document did not satisfy the glTF2 schema. Schema keyword: ", validator.GetInvalidSchemaKeyword(), ", document path: ", pathBuffer.GetString(), ", argument: ", argumentBuffer.GetString());
 2065|      0|            }
 2066|      0|        }
 2067|      0|    }
 2068|       |
 2069|       |    // Fill the buffer instance for the current file embedded contents
 2070|  2.39k|    if (mBodyLength > 0) {
  ------------------
  |  Branch (2070:9): [True: 2.02k, False: 368]
  ------------------
 2071|  2.02k|        if (!mBodyBuffer->LoadFromStream(*stream, mBodyLength, mBodyOffset)) {
  ------------------
  |  Branch (2071:13): [True: 15, False: 2.00k]
  ------------------
 2072|     15|            throw DeadlyImportError("GLTF: Unable to read gltf file");
 2073|     15|        }
 2074|  2.02k|    }
 2075|       |
 2076|       |    // Load the metadata
 2077|  2.37k|    asset.Read(doc);
 2078|  2.37k|    ReadExtensionsUsed(doc);
 2079|  2.37k|    ReadExtensionsRequired(doc);
 2080|       |
 2081|  2.37k|#ifndef ASSIMP_ENABLE_DRACO
 2082|       |    // Is Draco required?
 2083|  2.37k|    if (extensionsRequired.KHR_draco_mesh_compression) {
  ------------------
  |  Branch (2083:9): [True: 0, False: 2.37k]
  ------------------
 2084|      0|        throw DeadlyImportError("GLTF: Draco mesh compression not supported.");
 2085|      0|    }
 2086|  2.37k|#endif
 2087|       |
 2088|       |    // Prepare the dictionaries
 2089|  34.6k|    for (size_t i = 0; i < mDicts.size(); ++i) {
  ------------------
  |  Branch (2089:24): [True: 32.3k, False: 2.37k]
  ------------------
 2090|  32.3k|        mDicts[i]->AttachToDocument(doc);
 2091|  32.3k|    }
 2092|       |
 2093|       |    // Read the "extensions" property, then add it to each scene's metadata.
 2094|  2.37k|    CustomExtension customExtensions;
 2095|  2.37k|    if (Value *extensionsObject = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (2095:16): [True: 0, False: 2.37k]
  ------------------
 2096|      0|        customExtensions = glTF2::ReadExtensions("extensions", *extensionsObject);
 2097|      0|    }
 2098|       |
 2099|       |    // Read the "scene" property, which specifies which scene to load
 2100|       |    // and recursively load everything referenced by it
 2101|  2.37k|    unsigned int sceneIndex = 0;
 2102|  2.37k|    Value *curScene = FindUInt(doc, "scene");
 2103|  2.37k|    if (nullptr != curScene) {
  ------------------
  |  Branch (2103:9): [True: 2.10k, False: 266]
  ------------------
 2104|  2.10k|        sceneIndex = curScene->GetUint();
 2105|  2.10k|    }
 2106|       |
 2107|  2.37k|    if (Value *scenesArray = FindArray(doc, "scenes")) {
  ------------------
  |  Branch (2107:16): [True: 2.18k, False: 191]
  ------------------
 2108|  2.18k|        if (sceneIndex < scenesArray->Size()) {
  ------------------
  |  Branch (2108:13): [True: 2.16k, False: 21]
  ------------------
 2109|  2.16k|            this->scene = scenes.Retrieve(sceneIndex);
 2110|       |
 2111|  2.16k|            this->scene->customExtensions = customExtensions;
 2112|  2.16k|        }
 2113|  2.18k|    }
 2114|       |
 2115|  2.37k|    if (Value *skinsArray = FindArray(doc, "skins")) {
  ------------------
  |  Branch (2115:16): [True: 355, False: 2.02k]
  ------------------
 2116|    724|        for (unsigned int i = 0; i < skinsArray->Size(); ++i) {
  ------------------
  |  Branch (2116:34): [True: 369, False: 355]
  ------------------
 2117|    369|            skins.Retrieve(i);
 2118|    369|        }
 2119|    355|    }
 2120|       |
 2121|  2.37k|    if (Value *animsArray = FindArray(doc, "animations")) {
  ------------------
  |  Branch (2121:16): [True: 0, False: 2.37k]
  ------------------
 2122|      0|        for (unsigned int i = 0; i < animsArray->Size(); ++i) {
  ------------------
  |  Branch (2122:34): [True: 0, False: 0]
  ------------------
 2123|      0|            animations.Retrieve(i);
 2124|      0|        }
 2125|      0|    }
 2126|       |
 2127|       |    // Clean up
 2128|  30.4k|    for (size_t i = 0; i < mDicts.size(); ++i) {
  ------------------
  |  Branch (2128:24): [True: 28.0k, False: 2.37k]
  ------------------
 2129|  28.0k|        mDicts[i]->DetachFromDocument();
 2130|  28.0k|    }
 2131|  2.37k|}
_ZN5glTF25Asset7CanReadERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEb:
 2133|  4.40k|inline bool Asset::CanRead(const std::string &pFile, bool isBinary) {
 2134|  4.40k|    try {
 2135|  4.40k|        shared_ptr<IOStream> stream(OpenFile(pFile.c_str(), "rb", true));
 2136|  4.40k|        if (!stream) {
  ------------------
  |  Branch (2136:13): [True: 0, False: 4.40k]
  ------------------
 2137|      0|            return false;
 2138|      0|        }
 2139|  4.40k|        std::vector<char> sceneData;
 2140|  4.40k|        rapidjson::Document doc = ReadDocument(*stream, isBinary, sceneData);
 2141|  4.40k|        asset.Read(doc);
 2142|  4.40k|    } catch (...) {
 2143|  2.01k|        return false;
 2144|  2.01k|    }
 2145|  2.39k|    return true;
 2146|  4.40k|}
_ZN5glTF25Asset11SetAsBinaryEv:
 2148|  4.48k|inline void Asset::SetAsBinary() {
 2149|  4.48k|    if (!mBodyBuffer) {
  ------------------
  |  Branch (2149:9): [True: 4.48k, False: 0]
  ------------------
 2150|  4.48k|        mBodyBuffer = buffers.Create("binary_glTF");
 2151|  4.48k|        mBodyBuffer->MarkAsSpecial();
 2152|  4.48k|    }
 2153|  4.48k|}
_ZN5glTF25Asset22ReadExtensionsRequiredERN9rapidjson15GenericDocumentINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEES6_EE:
 2160|  2.31k|inline void Asset::ReadExtensionsRequired(Document &doc) {
 2161|  2.31k|    Value *extsRequired = FindArray(doc, "extensionsRequired");
 2162|  2.31k|    if (nullptr == extsRequired) {
  ------------------
  |  Branch (2162:9): [True: 2.31k, False: 0]
  ------------------
 2163|  2.31k|        return;
 2164|  2.31k|    }
 2165|       |
 2166|      0|    std::gltf_unordered_map<std::string, bool> exts;
 2167|      0|    for (unsigned int i = 0; i < extsRequired->Size(); ++i) {
  ------------------
  |  Branch (2167:30): [True: 0, False: 0]
  ------------------
 2168|      0|        if ((*extsRequired)[i].IsString()) {
  ------------------
  |  Branch (2168:13): [True: 0, False: 0]
  ------------------
 2169|      0|            exts[(*extsRequired)[i].GetString()] = true;
 2170|      0|        }
 2171|      0|    }
 2172|       |
 2173|      0|    CHECK_REQUIRED_EXT(KHR_draco_mesh_compression);
  ------------------
  |  | 2158|      0|    if (exts.find(#EXT) != exts.end()) extensionsRequired.EXT = true;
  |  |  ------------------
  |  |  |  Branch (2158:9): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2174|      0|    CHECK_REQUIRED_EXT(KHR_texture_basisu);
  ------------------
  |  | 2158|      0|    if (exts.find(#EXT) != exts.end()) extensionsRequired.EXT = true;
  |  |  ------------------
  |  |  |  Branch (2158:9): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2175|      0|    CHECK_REQUIRED_EXT(EXT_texture_webp);
  ------------------
  |  | 2158|      0|    if (exts.find(#EXT) != exts.end()) extensionsRequired.EXT = true;
  |  |  ------------------
  |  |  |  Branch (2158:9): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2176|       |
 2177|      0|#undef CHECK_REQUIRED_EXT
 2178|      0|}
_ZN5glTF25Asset18ReadExtensionsUsedERN9rapidjson15GenericDocumentINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEES6_EE:
 2180|  2.32k|inline void Asset::ReadExtensionsUsed(Document &doc) {
 2181|  2.32k|    Value *extsUsed = FindArray(doc, "extensionsUsed");
 2182|  2.32k|    if (!extsUsed) return;
  ------------------
  |  Branch (2182:9): [True: 1.90k, False: 412]
  ------------------
 2183|       |
 2184|    412|    std::gltf_unordered_map<std::string, bool> exts;
 2185|       |
 2186|  1.23k|    for (unsigned int i = 0; i < extsUsed->Size(); ++i) {
  ------------------
  |  Branch (2186:30): [True: 825, False: 412]
  ------------------
 2187|    825|        if ((*extsUsed)[i].IsString()) {
  ------------------
  |  Branch (2187:13): [True: 824, False: 1]
  ------------------
 2188|    824|            exts[(*extsUsed)[i].GetString()] = true;
 2189|    824|        }
 2190|    825|    }
 2191|       |
 2192|    412|    CHECK_EXT(KHR_materials_pbrSpecularGlossiness);
  ------------------
  |  |  237|    412|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 412]
  |  |  ------------------
  ------------------
 2193|    412|    CHECK_EXT(KHR_materials_specular);
  ------------------
  |  |  237|    412|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 412]
  |  |  ------------------
  ------------------
 2194|    412|    CHECK_EXT(KHR_materials_unlit);
  ------------------
  |  |  237|    412|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 412]
  |  |  ------------------
  ------------------
 2195|    412|    CHECK_EXT(KHR_lights_punctual);
  ------------------
  |  |  237|    412|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 412]
  |  |  ------------------
  ------------------
 2196|    412|    CHECK_EXT(KHR_texture_transform);
  ------------------
  |  |  237|    412|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 412]
  |  |  ------------------
  ------------------
 2197|    412|    CHECK_EXT(KHR_materials_sheen);
  ------------------
  |  |  237|    412|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 412]
  |  |  ------------------
  ------------------
 2198|    412|    CHECK_EXT(KHR_materials_clearcoat);
  ------------------
  |  |  237|    412|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 412]
  |  |  ------------------
  ------------------
 2199|    412|    CHECK_EXT(KHR_materials_transmission);
  ------------------
  |  |  237|    412|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 412]
  |  |  ------------------
  ------------------
 2200|    412|    CHECK_EXT(KHR_materials_volume);
  ------------------
  |  |  237|    412|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 325, False: 87]
  |  |  ------------------
  ------------------
 2201|    412|    CHECK_EXT(KHR_materials_ior);
  ------------------
  |  |  237|    412|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 412]
  |  |  ------------------
  ------------------
 2202|    412|    CHECK_EXT(KHR_materials_emissive_strength);
  ------------------
  |  |  237|    412|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 412]
  |  |  ------------------
  ------------------
 2203|    412|    CHECK_EXT(KHR_materials_anisotropy);
  ------------------
  |  |  237|    412|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 412]
  |  |  ------------------
  ------------------
 2204|    412|    CHECK_EXT(KHR_draco_mesh_compression);
  ------------------
  |  |  237|    412|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 412]
  |  |  ------------------
  ------------------
 2205|    412|    CHECK_EXT(KHR_texture_basisu);
  ------------------
  |  |  237|    412|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 412]
  |  |  ------------------
  ------------------
 2206|    412|    CHECK_EXT(EXT_texture_webp);
  ------------------
  |  |  237|    412|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 412]
  |  |  ------------------
  ------------------
 2207|       |
 2208|    412|#undef CHECK_EXT
 2209|    412|}
_ZN5glTF25Asset8OpenFileERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEPKcb:
 2211|  6.79k|inline IOStream *Asset::OpenFile(const std::string &path, const char *mode, bool /*absolute*/) {
 2212|  6.79k|#ifdef ASSIMP_API
 2213|  6.79k|    return mIOSystem->Open(path, mode);
 2214|       |#else
 2215|       |    if (path.size() < 2) return nullptr;
 2216|       |    if (!absolute && path[1] != ':' && path[0] != '/') { // relative?
 2217|       |        path = mCurrentAssetDir + path;
 2218|       |    }
 2219|       |    FILE *f = fopen(path.c_str(), mode);
 2220|       |    return f ? new IOStream(f) : nullptr;
 2221|       |#endif
 2222|  6.79k|}
_ZN5glTF28Accessor7Indexer8GetValueIjEET_i:
 1123|  29.9k|T Accessor::Indexer::GetValue(int i) {
 1124|  29.9k|    ai_assert(data);
 1125|  29.9k|    if (i * stride >= accessor.GetMaxByteSize()) {
  ------------------
  |  Branch (1125:9): [True: 0, False: 29.9k]
  ------------------
 1126|      0|        throw DeadlyImportError("GLTF: Invalid index ", i, ", count out of range for buffer with stride ", stride, " and size ", accessor.GetMaxByteSize(), ".");
 1127|      0|    }
 1128|       |    // Ensure that the memcpy doesn't overwrite the local.
 1129|  29.9k|    const size_t sizeToCopy = std::min(elemSize, sizeof(T));
 1130|  29.9k|    T value = T();
 1131|       |    // Assume platform endianness matches GLTF binary data (which is little-endian).
 1132|  29.9k|    memcpy(&value, data + i * stride, sizeToCopy);
 1133|  29.9k|    return value;
 1134|  29.9k|}
_ZN5glTF28LazyDictINS_8AccessorEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.31k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.31k|    Value *container = nullptr;
  407|  2.31k|    const char *context = nullptr;
  408|       |
  409|  2.31k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.31k]
  ------------------
  410|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (410:20): [True: 0, False: 0]
  ------------------
  411|      0|            container = FindObjectInContext(*exts, mExtId, "extensions");
  412|      0|            context = mExtId;
  413|      0|        }
  414|  2.31k|    } else {
  415|  2.31k|        container = &doc;
  416|  2.31k|        context = "the document";
  417|  2.31k|    }
  418|       |
  419|  2.31k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.31k, False: 0]
  ------------------
  420|  2.31k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.31k|    }
  422|  2.31k|}
_ZN5glTF28LazyDictINS_8AccessorEE18DetachFromDocumentEv:
  425|  2.00k|inline void LazyDict<T>::DetachFromDocument() {
  426|  2.00k|    mDict = nullptr;
  427|  2.00k|}
_ZN5glTF28LazyDictINS_9AnimationEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.31k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.31k|    Value *container = nullptr;
  407|  2.31k|    const char *context = nullptr;
  408|       |
  409|  2.31k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.31k]
  ------------------
  410|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (410:20): [True: 0, False: 0]
  ------------------
  411|      0|            container = FindObjectInContext(*exts, mExtId, "extensions");
  412|      0|            context = mExtId;
  413|      0|        }
  414|  2.31k|    } else {
  415|  2.31k|        container = &doc;
  416|  2.31k|        context = "the document";
  417|  2.31k|    }
  418|       |
  419|  2.31k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.31k, False: 0]
  ------------------
  420|  2.31k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.31k|    }
  422|  2.31k|}
_ZN5glTF28LazyDictINS_9AnimationEE18DetachFromDocumentEv:
  425|  2.00k|inline void LazyDict<T>::DetachFromDocument() {
  426|  2.00k|    mDict = nullptr;
  427|  2.00k|}
_ZN5glTF28LazyDictINS_6BufferEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.31k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.31k|    Value *container = nullptr;
  407|  2.31k|    const char *context = nullptr;
  408|       |
  409|  2.31k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.31k]
  ------------------
  410|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (410:20): [True: 0, False: 0]
  ------------------
  411|      0|            container = FindObjectInContext(*exts, mExtId, "extensions");
  412|      0|            context = mExtId;
  413|      0|        }
  414|  2.31k|    } else {
  415|  2.31k|        container = &doc;
  416|  2.31k|        context = "the document";
  417|  2.31k|    }
  418|       |
  419|  2.31k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.31k, False: 0]
  ------------------
  420|  2.31k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.31k|    }
  422|  2.31k|}
_ZN5glTF28LazyDictINS_6BufferEE18DetachFromDocumentEv:
  425|  2.00k|inline void LazyDict<T>::DetachFromDocument() {
  426|  2.00k|    mDict = nullptr;
  427|  2.00k|}
_ZN5glTF28LazyDictINS_10BufferViewEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.31k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.31k|    Value *container = nullptr;
  407|  2.31k|    const char *context = nullptr;
  408|       |
  409|  2.31k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.31k]
  ------------------
  410|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (410:20): [True: 0, False: 0]
  ------------------
  411|      0|            container = FindObjectInContext(*exts, mExtId, "extensions");
  412|      0|            context = mExtId;
  413|      0|        }
  414|  2.31k|    } else {
  415|  2.31k|        container = &doc;
  416|  2.31k|        context = "the document";
  417|  2.31k|    }
  418|       |
  419|  2.31k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.31k, False: 0]
  ------------------
  420|  2.31k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.31k|    }
  422|  2.31k|}
_ZN5glTF28LazyDictINS_10BufferViewEE18DetachFromDocumentEv:
  425|  2.00k|inline void LazyDict<T>::DetachFromDocument() {
  426|  2.00k|    mDict = nullptr;
  427|  2.00k|}
_ZN5glTF28LazyDictINS_6CameraEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.31k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.31k|    Value *container = nullptr;
  407|  2.31k|    const char *context = nullptr;
  408|       |
  409|  2.31k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.31k]
  ------------------
  410|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (410:20): [True: 0, False: 0]
  ------------------
  411|      0|            container = FindObjectInContext(*exts, mExtId, "extensions");
  412|      0|            context = mExtId;
  413|      0|        }
  414|  2.31k|    } else {
  415|  2.31k|        container = &doc;
  416|  2.31k|        context = "the document";
  417|  2.31k|    }
  418|       |
  419|  2.31k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.31k, False: 0]
  ------------------
  420|  2.31k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.31k|    }
  422|  2.31k|}
_ZN5glTF28LazyDictINS_6CameraEE18DetachFromDocumentEv:
  425|  2.00k|inline void LazyDict<T>::DetachFromDocument() {
  426|  2.00k|    mDict = nullptr;
  427|  2.00k|}
_ZN5glTF28LazyDictINS_5LightEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.31k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.31k|    Value *container = nullptr;
  407|  2.31k|    const char *context = nullptr;
  408|       |
  409|  2.31k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 2.31k, False: 0]
  ------------------
  410|  2.31k|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (410:20): [True: 0, False: 2.31k]
  ------------------
  411|      0|            container = FindObjectInContext(*exts, mExtId, "extensions");
  412|      0|            context = mExtId;
  413|      0|        }
  414|  2.31k|    } else {
  415|      0|        container = &doc;
  416|      0|        context = "the document";
  417|      0|    }
  418|       |
  419|  2.31k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 0, False: 2.31k]
  ------------------
  420|      0|        mDict = FindArrayInContext(*container, mDictId, context);
  421|      0|    }
  422|  2.31k|}
_ZN5glTF28LazyDictINS_5LightEE18DetachFromDocumentEv:
  425|  2.00k|inline void LazyDict<T>::DetachFromDocument() {
  426|  2.00k|    mDict = nullptr;
  427|  2.00k|}
_ZN5glTF28LazyDictINS_5ImageEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.31k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.31k|    Value *container = nullptr;
  407|  2.31k|    const char *context = nullptr;
  408|       |
  409|  2.31k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.31k]
  ------------------
  410|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (410:20): [True: 0, False: 0]
  ------------------
  411|      0|            container = FindObjectInContext(*exts, mExtId, "extensions");
  412|      0|            context = mExtId;
  413|      0|        }
  414|  2.31k|    } else {
  415|  2.31k|        container = &doc;
  416|  2.31k|        context = "the document";
  417|  2.31k|    }
  418|       |
  419|  2.31k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.31k, False: 0]
  ------------------
  420|  2.31k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.31k|    }
  422|  2.31k|}
_ZN5glTF28LazyDictINS_5ImageEE18DetachFromDocumentEv:
  425|  2.00k|inline void LazyDict<T>::DetachFromDocument() {
  426|  2.00k|    mDict = nullptr;
  427|  2.00k|}
_ZN5glTF28LazyDictINS_8MaterialEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.30k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.30k|    Value *container = nullptr;
  407|  2.30k|    const char *context = nullptr;
  408|       |
  409|  2.30k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.30k]
  ------------------
  410|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (410:20): [True: 0, False: 0]
  ------------------
  411|      0|            container = FindObjectInContext(*exts, mExtId, "extensions");
  412|      0|            context = mExtId;
  413|      0|        }
  414|  2.30k|    } else {
  415|  2.30k|        container = &doc;
  416|  2.30k|        context = "the document";
  417|  2.30k|    }
  418|       |
  419|  2.30k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.30k, False: 0]
  ------------------
  420|  2.30k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.30k|    }
  422|  2.30k|}
_ZN5glTF28LazyDictINS_8MaterialEE18DetachFromDocumentEv:
  425|  2.00k|inline void LazyDict<T>::DetachFromDocument() {
  426|  2.00k|    mDict = nullptr;
  427|  2.00k|}
_ZN5glTF28LazyDictINS_4MeshEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.30k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.30k|    Value *container = nullptr;
  407|  2.30k|    const char *context = nullptr;
  408|       |
  409|  2.30k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.30k]
  ------------------
  410|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (410:20): [True: 0, False: 0]
  ------------------
  411|      0|            container = FindObjectInContext(*exts, mExtId, "extensions");
  412|      0|            context = mExtId;
  413|      0|        }
  414|  2.30k|    } else {
  415|  2.30k|        container = &doc;
  416|  2.30k|        context = "the document";
  417|  2.30k|    }
  418|       |
  419|  2.30k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.30k, False: 0]
  ------------------
  420|  2.30k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.30k|    }
  422|  2.30k|}
_ZN5glTF28LazyDictINS_4MeshEE18DetachFromDocumentEv:
  425|  2.00k|inline void LazyDict<T>::DetachFromDocument() {
  426|  2.00k|    mDict = nullptr;
  427|  2.00k|}
_ZN5glTF28LazyDictINS_4NodeEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.30k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.30k|    Value *container = nullptr;
  407|  2.30k|    const char *context = nullptr;
  408|       |
  409|  2.30k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.30k]
  ------------------
  410|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (410:20): [True: 0, False: 0]
  ------------------
  411|      0|            container = FindObjectInContext(*exts, mExtId, "extensions");
  412|      0|            context = mExtId;
  413|      0|        }
  414|  2.30k|    } else {
  415|  2.30k|        container = &doc;
  416|  2.30k|        context = "the document";
  417|  2.30k|    }
  418|       |
  419|  2.30k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.30k, False: 0]
  ------------------
  420|  2.30k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.30k|    }
  422|  2.30k|}
_ZN5glTF28LazyDictINS_4NodeEE18DetachFromDocumentEv:
  425|  2.00k|inline void LazyDict<T>::DetachFromDocument() {
  426|  2.00k|    mDict = nullptr;
  427|  2.00k|}
_ZN5glTF28LazyDictINS_7SamplerEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.30k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.30k|    Value *container = nullptr;
  407|  2.30k|    const char *context = nullptr;
  408|       |
  409|  2.30k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.30k]
  ------------------
  410|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (410:20): [True: 0, False: 0]
  ------------------
  411|      0|            container = FindObjectInContext(*exts, mExtId, "extensions");
  412|      0|            context = mExtId;
  413|      0|        }
  414|  2.30k|    } else {
  415|  2.30k|        container = &doc;
  416|  2.30k|        context = "the document";
  417|  2.30k|    }
  418|       |
  419|  2.30k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.30k, False: 0]
  ------------------
  420|  2.30k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.30k|    }
  422|  2.30k|}
_ZN5glTF28LazyDictINS_7SamplerEE18DetachFromDocumentEv:
  425|  2.00k|inline void LazyDict<T>::DetachFromDocument() {
  426|  2.00k|    mDict = nullptr;
  427|  2.00k|}
_ZN5glTF28LazyDictINS_5SceneEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.30k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.30k|    Value *container = nullptr;
  407|  2.30k|    const char *context = nullptr;
  408|       |
  409|  2.30k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.30k]
  ------------------
  410|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (410:20): [True: 0, False: 0]
  ------------------
  411|      0|            container = FindObjectInContext(*exts, mExtId, "extensions");
  412|      0|            context = mExtId;
  413|      0|        }
  414|  2.30k|    } else {
  415|  2.30k|        container = &doc;
  416|  2.30k|        context = "the document";
  417|  2.30k|    }
  418|       |
  419|  2.30k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.30k, False: 0]
  ------------------
  420|  2.30k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.30k|    }
  422|  2.30k|}
_ZN5glTF28LazyDictINS_5SceneEE18DetachFromDocumentEv:
  425|  2.00k|inline void LazyDict<T>::DetachFromDocument() {
  426|  2.00k|    mDict = nullptr;
  427|  2.00k|}
_ZN5glTF28LazyDictINS_4SkinEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.30k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.30k|    Value *container = nullptr;
  407|  2.30k|    const char *context = nullptr;
  408|       |
  409|  2.30k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.30k]
  ------------------
  410|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (410:20): [True: 0, False: 0]
  ------------------
  411|      0|            container = FindObjectInContext(*exts, mExtId, "extensions");
  412|      0|            context = mExtId;
  413|      0|        }
  414|  2.30k|    } else {
  415|  2.30k|        container = &doc;
  416|  2.30k|        context = "the document";
  417|  2.30k|    }
  418|       |
  419|  2.30k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.30k, False: 0]
  ------------------
  420|  2.30k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.30k|    }
  422|  2.30k|}
_ZN5glTF28LazyDictINS_4SkinEE18DetachFromDocumentEv:
  425|  2.00k|inline void LazyDict<T>::DetachFromDocument() {
  426|  2.00k|    mDict = nullptr;
  427|  2.00k|}
_ZN5glTF28LazyDictINS_7TextureEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.30k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.30k|    Value *container = nullptr;
  407|  2.30k|    const char *context = nullptr;
  408|       |
  409|  2.30k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.30k]
  ------------------
  410|      0|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (410:20): [True: 0, False: 0]
  ------------------
  411|      0|            container = FindObjectInContext(*exts, mExtId, "extensions");
  412|      0|            context = mExtId;
  413|      0|        }
  414|  2.30k|    } else {
  415|  2.30k|        container = &doc;
  416|  2.30k|        context = "the document";
  417|  2.30k|    }
  418|       |
  419|  2.30k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.30k, False: 0]
  ------------------
  420|  2.30k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.30k|    }
  422|  2.30k|}
_ZN5glTF28LazyDictINS_7TextureEE18DetachFromDocumentEv:
  425|  2.00k|inline void LazyDict<T>::DetachFromDocument() {
  426|  2.00k|    mDict = nullptr;
  427|  2.00k|}
_ZN5glTF28LazyDictINS_6BufferEE8RetrieveEj:
  473|  6.69k|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|  6.69k|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|  6.69k|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 6.68k, False: 10]
  ------------------
  476|  6.68k|        return Ref<T>(mObjs, it->second);
  477|  6.68k|    }
  478|       |
  479|       |    // read it from the JSON object
  480|     10|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 1, False: 9]
  ------------------
  481|      1|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      1|    }
  483|       |
  484|      9|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 9]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|      9|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 9, False: 0]
  ------------------
  489|      9|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|      9|    }
  491|       |
  492|      0|    Value &obj = (*mDict)[i];
  493|       |
  494|      0|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 0, False: 0]
  ------------------
  495|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      0|    }
  497|       |
  498|      0|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 0, False: 0]
  ------------------
  499|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|      0|    }
  501|      0|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|      0|    auto inst = std::unique_ptr<T>(new T());
  505|       |    // Try to make this human readable so it can be used in error messages.
  506|      0|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|      0|    inst->oIndex = i;
  508|      0|    ReadMember(obj, "name", inst->name);
  509|      0|    inst->Read(obj, mAsset);
  510|      0|    inst->ReadExtensions(obj);
  511|      0|    inst->ReadExtras(obj);
  512|       |
  513|      0|    Ref<T> result = Add(inst.release());
  514|      0|    mRecursiveReferenceCheck.erase(i);
  515|      0|    return result;
  516|      0|}
_ZN5glTF28LazyDictINS_6BufferEE3AddEPS1_:
  536|  4.48k|Ref<T> LazyDict<T>::Add(T *obj) {
  537|  4.48k|    unsigned int idx = unsigned(mObjs.size());
  538|  4.48k|    mObjs.push_back(obj);
  539|  4.48k|    mObjsByOIndex[obj->oIndex] = idx;
  540|  4.48k|    mObjsById[obj->id] = idx;
  541|  4.48k|    return Ref<T>(mObjs, idx);
  542|  4.48k|}
_ZN5glTF28LazyDictINS_10BufferViewEE8RetrieveEj:
  473|  6.98k|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|  6.98k|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|  6.98k|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 269, False: 6.71k]
  ------------------
  476|    269|        return Ref<T>(mObjs, it->second);
  477|    269|    }
  478|       |
  479|       |    // read it from the JSON object
  480|  6.71k|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 7, False: 6.71k]
  ------------------
  481|      7|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      7|    }
  483|       |
  484|  6.71k|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 6.71k]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|  6.71k|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 6, False: 6.70k]
  ------------------
  489|      6|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|      6|    }
  491|       |
  492|  6.70k|    Value &obj = (*mDict)[i];
  493|       |
  494|  6.70k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 0, False: 6.70k]
  ------------------
  495|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      0|    }
  497|       |
  498|  6.70k|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 0, False: 6.70k]
  ------------------
  499|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|      0|    }
  501|  6.70k|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|  6.70k|    auto inst = std::unique_ptr<T>(new T());
  505|       |    // Try to make this human readable so it can be used in error messages.
  506|  6.70k|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|  6.70k|    inst->oIndex = i;
  508|  6.70k|    ReadMember(obj, "name", inst->name);
  509|  6.70k|    inst->Read(obj, mAsset);
  510|  6.70k|    inst->ReadExtensions(obj);
  511|  6.70k|    inst->ReadExtras(obj);
  512|       |
  513|  6.70k|    Ref<T> result = Add(inst.release());
  514|  6.70k|    mRecursiveReferenceCheck.erase(i);
  515|  6.70k|    return result;
  516|  6.70k|}
_ZN5glTF28LazyDictINS_10BufferViewEE3AddEPS1_:
  536|  6.66k|Ref<T> LazyDict<T>::Add(T *obj) {
  537|  6.66k|    unsigned int idx = unsigned(mObjs.size());
  538|  6.66k|    mObjs.push_back(obj);
  539|  6.66k|    mObjsByOIndex[obj->oIndex] = idx;
  540|  6.66k|    mObjsById[obj->id] = idx;
  541|  6.66k|    return Ref<T>(mObjs, idx);
  542|  6.66k|}
_ZN5glTF28LazyDictINS_5ImageEE8RetrieveEj:
  473|     62|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|     62|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|     62|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 0, False: 62]
  ------------------
  476|      0|        return Ref<T>(mObjs, it->second);
  477|      0|    }
  478|       |
  479|       |    // read it from the JSON object
  480|     62|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 1, False: 61]
  ------------------
  481|      1|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      1|    }
  483|       |
  484|     61|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 61]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|     61|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 1, False: 60]
  ------------------
  489|      1|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|      1|    }
  491|       |
  492|     60|    Value &obj = (*mDict)[i];
  493|       |
  494|     60|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 0, False: 60]
  ------------------
  495|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      0|    }
  497|       |
  498|     60|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 0, False: 60]
  ------------------
  499|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|      0|    }
  501|     60|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|     60|    auto inst = std::unique_ptr<T>(new T());
  505|       |    // Try to make this human readable so it can be used in error messages.
  506|     60|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|     60|    inst->oIndex = i;
  508|     60|    ReadMember(obj, "name", inst->name);
  509|     60|    inst->Read(obj, mAsset);
  510|     60|    inst->ReadExtensions(obj);
  511|     60|    inst->ReadExtras(obj);
  512|       |
  513|     60|    Ref<T> result = Add(inst.release());
  514|     60|    mRecursiveReferenceCheck.erase(i);
  515|     60|    return result;
  516|     60|}
_ZN5glTF28LazyDictINS_5ImageEE3AddEPS1_:
  536|     55|Ref<T> LazyDict<T>::Add(T *obj) {
  537|     55|    unsigned int idx = unsigned(mObjs.size());
  538|     55|    mObjs.push_back(obj);
  539|     55|    mObjsByOIndex[obj->oIndex] = idx;
  540|     55|    mObjsById[obj->id] = idx;
  541|     55|    return Ref<T>(mObjs, idx);
  542|     55|}
_ZN5glTF28LazyDictINS_7SamplerEE8RetrieveEj:
  473|     61|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|     61|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|     61|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 0, False: 61]
  ------------------
  476|      0|        return Ref<T>(mObjs, it->second);
  477|      0|    }
  478|       |
  479|       |    // read it from the JSON object
  480|     61|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 1, False: 60]
  ------------------
  481|      1|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      1|    }
  483|       |
  484|     60|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 60]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|     60|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 1, False: 59]
  ------------------
  489|      1|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|      1|    }
  491|       |
  492|     59|    Value &obj = (*mDict)[i];
  493|       |
  494|     59|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 0, False: 59]
  ------------------
  495|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      0|    }
  497|       |
  498|     59|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 0, False: 59]
  ------------------
  499|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|      0|    }
  501|     59|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|     59|    auto inst = std::unique_ptr<T>(new T());
  505|       |    // Try to make this human readable so it can be used in error messages.
  506|     59|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|     59|    inst->oIndex = i;
  508|     59|    ReadMember(obj, "name", inst->name);
  509|     59|    inst->Read(obj, mAsset);
  510|     59|    inst->ReadExtensions(obj);
  511|     59|    inst->ReadExtras(obj);
  512|       |
  513|     59|    Ref<T> result = Add(inst.release());
  514|     59|    mRecursiveReferenceCheck.erase(i);
  515|     59|    return result;
  516|     59|}
_ZN5glTF28LazyDictINS_7SamplerEE3AddEPS1_:
  536|     59|Ref<T> LazyDict<T>::Add(T *obj) {
  537|     59|    unsigned int idx = unsigned(mObjs.size());
  538|     59|    mObjs.push_back(obj);
  539|     59|    mObjsByOIndex[obj->oIndex] = idx;
  540|     59|    mObjsById[obj->id] = idx;
  541|     59|    return Ref<T>(mObjs, idx);
  542|     59|}
_ZN5glTF28LazyDictINS_7TextureEE8RetrieveEj:
  473|     77|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|     77|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|     77|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 0, False: 77]
  ------------------
  476|      0|        return Ref<T>(mObjs, it->second);
  477|      0|    }
  478|       |
  479|       |    // read it from the JSON object
  480|     77|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 1, False: 76]
  ------------------
  481|      1|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      1|    }
  483|       |
  484|     76|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 76]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|     76|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 2, False: 74]
  ------------------
  489|      2|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|      2|    }
  491|       |
  492|     74|    Value &obj = (*mDict)[i];
  493|       |
  494|     74|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 0, False: 74]
  ------------------
  495|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      0|    }
  497|       |
  498|     74|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 0, False: 74]
  ------------------
  499|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|      0|    }
  501|     74|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|     74|    auto inst = std::unique_ptr<T>(new T());
  505|       |    // Try to make this human readable so it can be used in error messages.
  506|     74|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|     74|    inst->oIndex = i;
  508|     74|    ReadMember(obj, "name", inst->name);
  509|     74|    inst->Read(obj, mAsset);
  510|     74|    inst->ReadExtensions(obj);
  511|     74|    inst->ReadExtras(obj);
  512|       |
  513|     74|    Ref<T> result = Add(inst.release());
  514|     74|    mRecursiveReferenceCheck.erase(i);
  515|     74|    return result;
  516|     74|}
_ZN5glTF28LazyDictINS_7TextureEE3AddEPS1_:
  536|     64|Ref<T> LazyDict<T>::Add(T *obj) {
  537|     64|    unsigned int idx = unsigned(mObjs.size());
  538|     64|    mObjs.push_back(obj);
  539|     64|    mObjsByOIndex[obj->oIndex] = idx;
  540|     64|    mObjsById[obj->id] = idx;
  541|     64|    return Ref<T>(mObjs, idx);
  542|     64|}
_ZN5glTF28LazyDictINS_8AccessorEE8RetrieveEj:
  473|  7.37k|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|  7.37k|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|  7.37k|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 280, False: 7.09k]
  ------------------
  476|    280|        return Ref<T>(mObjs, it->second);
  477|    280|    }
  478|       |
  479|       |    // read it from the JSON object
  480|  7.09k|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 1, False: 7.09k]
  ------------------
  481|      1|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      1|    }
  483|       |
  484|  7.09k|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 7.09k]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|  7.09k|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 12, False: 7.08k]
  ------------------
  489|     12|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|     12|    }
  491|       |
  492|  7.08k|    Value &obj = (*mDict)[i];
  493|       |
  494|  7.08k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 0, False: 7.08k]
  ------------------
  495|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      0|    }
  497|       |
  498|  7.08k|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 0, False: 7.08k]
  ------------------
  499|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|      0|    }
  501|  7.08k|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|  7.08k|    auto inst = std::unique_ptr<T>(new T());
  505|       |    // Try to make this human readable so it can be used in error messages.
  506|  7.08k|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|  7.08k|    inst->oIndex = i;
  508|  7.08k|    ReadMember(obj, "name", inst->name);
  509|  7.08k|    inst->Read(obj, mAsset);
  510|  7.08k|    inst->ReadExtensions(obj);
  511|  7.08k|    inst->ReadExtras(obj);
  512|       |
  513|  7.08k|    Ref<T> result = Add(inst.release());
  514|  7.08k|    mRecursiveReferenceCheck.erase(i);
  515|  7.08k|    return result;
  516|  7.08k|}
_ZN5glTF28LazyDictINS_8AccessorEE3AddEPS1_:
  536|  6.95k|Ref<T> LazyDict<T>::Add(T *obj) {
  537|  6.95k|    unsigned int idx = unsigned(mObjs.size());
  538|  6.95k|    mObjs.push_back(obj);
  539|  6.95k|    mObjsByOIndex[obj->oIndex] = idx;
  540|  6.95k|    mObjsById[obj->id] = idx;
  541|  6.95k|    return Ref<T>(mObjs, idx);
  542|  6.95k|}
_ZN5glTF28LazyDictINS_8MaterialEE8RetrieveEj:
  473|  1.54k|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|  1.54k|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|  1.54k|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 0, False: 1.54k]
  ------------------
  476|      0|        return Ref<T>(mObjs, it->second);
  477|      0|    }
  478|       |
  479|       |    // read it from the JSON object
  480|  1.54k|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 2, False: 1.54k]
  ------------------
  481|      2|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      2|    }
  483|       |
  484|  1.54k|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 1.54k]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|  1.54k|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 3, False: 1.54k]
  ------------------
  489|      3|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|      3|    }
  491|       |
  492|  1.54k|    Value &obj = (*mDict)[i];
  493|       |
  494|  1.54k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 0, False: 1.54k]
  ------------------
  495|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      0|    }
  497|       |
  498|  1.54k|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 0, False: 1.54k]
  ------------------
  499|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|      0|    }
  501|  1.54k|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|  1.54k|    auto inst = std::unique_ptr<T>(new T());
  505|       |    // Try to make this human readable so it can be used in error messages.
  506|  1.54k|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|  1.54k|    inst->oIndex = i;
  508|  1.54k|    ReadMember(obj, "name", inst->name);
  509|  1.54k|    inst->Read(obj, mAsset);
  510|  1.54k|    inst->ReadExtensions(obj);
  511|  1.54k|    inst->ReadExtras(obj);
  512|       |
  513|  1.54k|    Ref<T> result = Add(inst.release());
  514|  1.54k|    mRecursiveReferenceCheck.erase(i);
  515|  1.54k|    return result;
  516|  1.54k|}
_ZN5glTF28LazyDictINS_8MaterialEE3AddEPS1_:
  536|  1.52k|Ref<T> LazyDict<T>::Add(T *obj) {
  537|  1.52k|    unsigned int idx = unsigned(mObjs.size());
  538|  1.52k|    mObjs.push_back(obj);
  539|  1.52k|    mObjsByOIndex[obj->oIndex] = idx;
  540|  1.52k|    mObjsById[obj->id] = idx;
  541|  1.52k|    return Ref<T>(mObjs, idx);
  542|  1.52k|}
_ZN5glTF28LazyDictINS_4NodeEE8RetrieveEj:
  473|  14.7k|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|  14.7k|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|  14.7k|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 3.11k, False: 11.6k]
  ------------------
  476|  3.11k|        return Ref<T>(mObjs, it->second);
  477|  3.11k|    }
  478|       |
  479|       |    // read it from the JSON object
  480|  11.6k|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 6, False: 11.6k]
  ------------------
  481|      6|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      6|    }
  483|       |
  484|  11.6k|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 11.6k]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|  11.6k|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 42, False: 11.5k]
  ------------------
  489|     42|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|     42|    }
  491|       |
  492|  11.5k|    Value &obj = (*mDict)[i];
  493|       |
  494|  11.5k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 1, False: 11.5k]
  ------------------
  495|      1|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      1|    }
  497|       |
  498|  11.5k|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 17, False: 11.5k]
  ------------------
  499|     17|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|     17|    }
  501|  11.5k|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|  11.5k|    auto inst = std::unique_ptr<T>(new T());
  505|       |    // Try to make this human readable so it can be used in error messages.
  506|  11.5k|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|  11.5k|    inst->oIndex = i;
  508|  11.5k|    ReadMember(obj, "name", inst->name);
  509|  11.5k|    inst->Read(obj, mAsset);
  510|  11.5k|    inst->ReadExtensions(obj);
  511|  11.5k|    inst->ReadExtras(obj);
  512|       |
  513|  11.5k|    Ref<T> result = Add(inst.release());
  514|  11.5k|    mRecursiveReferenceCheck.erase(i);
  515|  11.5k|    return result;
  516|  11.5k|}
_ZN5glTF28LazyDictINS_4NodeEE3AddEPS1_:
  536|  11.0k|Ref<T> LazyDict<T>::Add(T *obj) {
  537|  11.0k|    unsigned int idx = unsigned(mObjs.size());
  538|  11.0k|    mObjs.push_back(obj);
  539|  11.0k|    mObjsByOIndex[obj->oIndex] = idx;
  540|  11.0k|    mObjsById[obj->id] = idx;
  541|  11.0k|    return Ref<T>(mObjs, idx);
  542|  11.0k|}
_ZN5glTF28LazyDictINS_4MeshEE8RetrieveEj:
  473|  1.96k|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|  1.96k|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|  1.96k|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 0, False: 1.96k]
  ------------------
  476|      0|        return Ref<T>(mObjs, it->second);
  477|      0|    }
  478|       |
  479|       |    // read it from the JSON object
  480|  1.96k|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 8, False: 1.96k]
  ------------------
  481|      8|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      8|    }
  483|       |
  484|  1.96k|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 1.96k]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|  1.96k|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 7, False: 1.95k]
  ------------------
  489|      7|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|      7|    }
  491|       |
  492|  1.95k|    Value &obj = (*mDict)[i];
  493|       |
  494|  1.95k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 1, False: 1.95k]
  ------------------
  495|      1|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      1|    }
  497|       |
  498|  1.95k|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 0, False: 1.95k]
  ------------------
  499|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|      0|    }
  501|  1.95k|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|  1.95k|    auto inst = std::unique_ptr<T>(new T());
  505|       |    // Try to make this human readable so it can be used in error messages.
  506|  1.95k|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|  1.95k|    inst->oIndex = i;
  508|  1.95k|    ReadMember(obj, "name", inst->name);
  509|  1.95k|    inst->Read(obj, mAsset);
  510|  1.95k|    inst->ReadExtensions(obj);
  511|  1.95k|    inst->ReadExtras(obj);
  512|       |
  513|  1.95k|    Ref<T> result = Add(inst.release());
  514|  1.95k|    mRecursiveReferenceCheck.erase(i);
  515|  1.95k|    return result;
  516|  1.95k|}
_ZN5glTF28LazyDictINS_4MeshEE3AddEPS1_:
  536|  1.78k|Ref<T> LazyDict<T>::Add(T *obj) {
  537|  1.78k|    unsigned int idx = unsigned(mObjs.size());
  538|  1.78k|    mObjs.push_back(obj);
  539|  1.78k|    mObjsByOIndex[obj->oIndex] = idx;
  540|  1.78k|    mObjsById[obj->id] = idx;
  541|  1.78k|    return Ref<T>(mObjs, idx);
  542|  1.78k|}
_ZN5glTF28LazyDictINS_4SkinEE3GetEj:
  519|    320|Ref<T> LazyDict<T>::Get(unsigned int i) {
  520|    320|    return Ref<T>(mObjs, i);
  521|    320|}
_ZN5glTF28LazyDictINS_5SceneEE8RetrieveEj:
  473|  2.16k|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|  2.16k|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|  2.16k|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 0, False: 2.16k]
  ------------------
  476|      0|        return Ref<T>(mObjs, it->second);
  477|      0|    }
  478|       |
  479|       |    // read it from the JSON object
  480|  2.16k|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 0, False: 2.16k]
  ------------------
  481|      0|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      0|    }
  483|       |
  484|  2.16k|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 2.16k]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|  2.16k|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 0, False: 2.16k]
  ------------------
  489|      0|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|      0|    }
  491|       |
  492|  2.16k|    Value &obj = (*mDict)[i];
  493|       |
  494|  2.16k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 3, False: 2.16k]
  ------------------
  495|      3|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      3|    }
  497|       |
  498|  2.16k|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 0, False: 2.16k]
  ------------------
  499|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|      0|    }
  501|  2.16k|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|  2.16k|    auto inst = std::unique_ptr<T>(new T());
  505|       |    // Try to make this human readable so it can be used in error messages.
  506|  2.16k|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|  2.16k|    inst->oIndex = i;
  508|  2.16k|    ReadMember(obj, "name", inst->name);
  509|  2.16k|    inst->Read(obj, mAsset);
  510|  2.16k|    inst->ReadExtensions(obj);
  511|  2.16k|    inst->ReadExtras(obj);
  512|       |
  513|  2.16k|    Ref<T> result = Add(inst.release());
  514|  2.16k|    mRecursiveReferenceCheck.erase(i);
  515|  2.16k|    return result;
  516|  2.16k|}
_ZN5glTF28LazyDictINS_5SceneEE3AddEPS1_:
  536|  1.90k|Ref<T> LazyDict<T>::Add(T *obj) {
  537|  1.90k|    unsigned int idx = unsigned(mObjs.size());
  538|  1.90k|    mObjs.push_back(obj);
  539|  1.90k|    mObjsByOIndex[obj->oIndex] = idx;
  540|  1.90k|    mObjsById[obj->id] = idx;
  541|  1.90k|    return Ref<T>(mObjs, idx);
  542|  1.90k|}
_ZN5glTF28LazyDictINS_4SkinEE8RetrieveEj:
  473|    369|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|    369|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|    369|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 0, False: 369]
  ------------------
  476|      0|        return Ref<T>(mObjs, it->second);
  477|      0|    }
  478|       |
  479|       |    // read it from the JSON object
  480|    369|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 0, False: 369]
  ------------------
  481|      0|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      0|    }
  483|       |
  484|    369|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 369]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|    369|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 0, False: 369]
  ------------------
  489|      0|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|      0|    }
  491|       |
  492|    369|    Value &obj = (*mDict)[i];
  493|       |
  494|    369|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 0, False: 369]
  ------------------
  495|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      0|    }
  497|       |
  498|    369|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 0, False: 369]
  ------------------
  499|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|      0|    }
  501|    369|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|    369|    auto inst = std::unique_ptr<T>(new T());
  505|       |    // Try to make this human readable so it can be used in error messages.
  506|    369|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|    369|    inst->oIndex = i;
  508|    369|    ReadMember(obj, "name", inst->name);
  509|    369|    inst->Read(obj, mAsset);
  510|    369|    inst->ReadExtensions(obj);
  511|    369|    inst->ReadExtras(obj);
  512|       |
  513|    369|    Ref<T> result = Add(inst.release());
  514|    369|    mRecursiveReferenceCheck.erase(i);
  515|    369|    return result;
  516|    369|}
_ZN5glTF28LazyDictINS_4SkinEE3AddEPS1_:
  536|    337|Ref<T> LazyDict<T>::Add(T *obj) {
  537|    337|    unsigned int idx = unsigned(mObjs.size());
  538|    337|    mObjs.push_back(obj);
  539|    337|    mObjsByOIndex[obj->oIndex] = idx;
  540|    337|    mObjsById[obj->id] = idx;
  541|    337|    return Ref<T>(mObjs, idx);
  542|    337|}
_ZN5glTF28LazyDictINS_6BufferEE6CreateEPKc:
  545|  4.48k|Ref<T> LazyDict<T>::Create(const char *id) {
  546|  4.48k|    T *inst = new T();
  547|  4.48k|    unsigned int idx = unsigned(mObjs.size());
  548|  4.48k|    inst->id = id;
  549|  4.48k|    inst->index = idx;
  550|  4.48k|    inst->oIndex = idx;
  551|  4.48k|    return Add(inst);
  552|  4.48k|}
_ZN5glTF28LazyDictINS_8AccessorEEC2ERNS_5AssetEPKcS6_:
  390|  6.79k|        mDictId(dictId),
  391|  6.79k|        mExtId(extId),
  392|  6.79k|        mDict(nullptr),
  393|  6.79k|        mAsset(asset) {
  394|  6.79k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.79k|}
_ZN5glTF28LazyDictINS_9AnimationEEC2ERNS_5AssetEPKcS6_:
  390|  6.79k|        mDictId(dictId),
  391|  6.79k|        mExtId(extId),
  392|  6.79k|        mDict(nullptr),
  393|  6.79k|        mAsset(asset) {
  394|  6.79k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.79k|}
_ZN5glTF28LazyDictINS_6BufferEEC2ERNS_5AssetEPKcS6_:
  390|  6.79k|        mDictId(dictId),
  391|  6.79k|        mExtId(extId),
  392|  6.79k|        mDict(nullptr),
  393|  6.79k|        mAsset(asset) {
  394|  6.79k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.79k|}
_ZN5glTF28LazyDictINS_10BufferViewEEC2ERNS_5AssetEPKcS6_:
  390|  6.79k|        mDictId(dictId),
  391|  6.79k|        mExtId(extId),
  392|  6.79k|        mDict(nullptr),
  393|  6.79k|        mAsset(asset) {
  394|  6.79k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.79k|}
_ZN5glTF28LazyDictINS_6CameraEEC2ERNS_5AssetEPKcS6_:
  390|  6.79k|        mDictId(dictId),
  391|  6.79k|        mExtId(extId),
  392|  6.79k|        mDict(nullptr),
  393|  6.79k|        mAsset(asset) {
  394|  6.79k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.79k|}
_ZN5glTF28LazyDictINS_5LightEEC2ERNS_5AssetEPKcS6_:
  390|  6.79k|        mDictId(dictId),
  391|  6.79k|        mExtId(extId),
  392|  6.79k|        mDict(nullptr),
  393|  6.79k|        mAsset(asset) {
  394|  6.79k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.79k|}
_ZN5glTF28LazyDictINS_5ImageEEC2ERNS_5AssetEPKcS6_:
  390|  6.79k|        mDictId(dictId),
  391|  6.79k|        mExtId(extId),
  392|  6.79k|        mDict(nullptr),
  393|  6.79k|        mAsset(asset) {
  394|  6.79k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.79k|}
_ZN5glTF28LazyDictINS_8MaterialEEC2ERNS_5AssetEPKcS6_:
  390|  6.79k|        mDictId(dictId),
  391|  6.79k|        mExtId(extId),
  392|  6.79k|        mDict(nullptr),
  393|  6.79k|        mAsset(asset) {
  394|  6.79k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.79k|}
_ZN5glTF28LazyDictINS_4MeshEEC2ERNS_5AssetEPKcS6_:
  390|  6.79k|        mDictId(dictId),
  391|  6.79k|        mExtId(extId),
  392|  6.79k|        mDict(nullptr),
  393|  6.79k|        mAsset(asset) {
  394|  6.79k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.79k|}
_ZN5glTF28LazyDictINS_4NodeEEC2ERNS_5AssetEPKcS6_:
  390|  6.79k|        mDictId(dictId),
  391|  6.79k|        mExtId(extId),
  392|  6.79k|        mDict(nullptr),
  393|  6.79k|        mAsset(asset) {
  394|  6.79k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.79k|}
_ZN5glTF28LazyDictINS_7SamplerEEC2ERNS_5AssetEPKcS6_:
  390|  6.79k|        mDictId(dictId),
  391|  6.79k|        mExtId(extId),
  392|  6.79k|        mDict(nullptr),
  393|  6.79k|        mAsset(asset) {
  394|  6.79k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.79k|}
_ZN5glTF28LazyDictINS_5SceneEEC2ERNS_5AssetEPKcS6_:
  390|  6.79k|        mDictId(dictId),
  391|  6.79k|        mExtId(extId),
  392|  6.79k|        mDict(nullptr),
  393|  6.79k|        mAsset(asset) {
  394|  6.79k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.79k|}
_ZN5glTF28LazyDictINS_4SkinEEC2ERNS_5AssetEPKcS6_:
  390|  6.79k|        mDictId(dictId),
  391|  6.79k|        mExtId(extId),
  392|  6.79k|        mDict(nullptr),
  393|  6.79k|        mAsset(asset) {
  394|  6.79k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.79k|}
_ZN5glTF28LazyDictINS_7TextureEEC2ERNS_5AssetEPKcS6_:
  390|  6.79k|        mDictId(dictId),
  391|  6.79k|        mExtId(extId),
  392|  6.79k|        mDict(nullptr),
  393|  6.79k|        mAsset(asset) {
  394|  6.79k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.79k|}
_ZN5glTF28LazyDictINS_7TextureEED2Ev:
  398|  6.79k|inline LazyDict<T>::~LazyDict() {
  399|  6.86k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 64, False: 6.79k]
  ------------------
  400|     64|        delete mObjs[i];
  401|     64|    }
  402|  6.79k|}
_ZN5glTF28LazyDictINS_4SkinEED2Ev:
  398|  6.79k|inline LazyDict<T>::~LazyDict() {
  399|  7.13k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 337, False: 6.79k]
  ------------------
  400|    337|        delete mObjs[i];
  401|    337|    }
  402|  6.79k|}
_ZN5glTF28LazyDictINS_5SceneEED2Ev:
  398|  6.79k|inline LazyDict<T>::~LazyDict() {
  399|  8.70k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 1.90k, False: 6.79k]
  ------------------
  400|  1.90k|        delete mObjs[i];
  401|  1.90k|    }
  402|  6.79k|}
_ZN5glTF28LazyDictINS_7SamplerEED2Ev:
  398|  6.79k|inline LazyDict<T>::~LazyDict() {
  399|  6.85k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 59, False: 6.79k]
  ------------------
  400|     59|        delete mObjs[i];
  401|     59|    }
  402|  6.79k|}
_ZN5glTF28LazyDictINS_4NodeEED2Ev:
  398|  6.79k|inline LazyDict<T>::~LazyDict() {
  399|  17.8k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 11.0k, False: 6.79k]
  ------------------
  400|  11.0k|        delete mObjs[i];
  401|  11.0k|    }
  402|  6.79k|}
_ZN5glTF28LazyDictINS_4MeshEED2Ev:
  398|  6.79k|inline LazyDict<T>::~LazyDict() {
  399|  8.58k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 1.78k, False: 6.79k]
  ------------------
  400|  1.78k|        delete mObjs[i];
  401|  1.78k|    }
  402|  6.79k|}
_ZN5glTF28LazyDictINS_8MaterialEED2Ev:
  398|  6.79k|inline LazyDict<T>::~LazyDict() {
  399|  8.32k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 1.52k, False: 6.79k]
  ------------------
  400|  1.52k|        delete mObjs[i];
  401|  1.52k|    }
  402|  6.79k|}
_ZN5glTF28LazyDictINS_5ImageEED2Ev:
  398|  6.79k|inline LazyDict<T>::~LazyDict() {
  399|  6.85k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 55, False: 6.79k]
  ------------------
  400|     55|        delete mObjs[i];
  401|     55|    }
  402|  6.79k|}
_ZN5glTF28LazyDictINS_5LightEED2Ev:
  398|  6.79k|inline LazyDict<T>::~LazyDict() {
  399|  6.79k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 0, False: 6.79k]
  ------------------
  400|      0|        delete mObjs[i];
  401|      0|    }
  402|  6.79k|}
_ZN5glTF28LazyDictINS_6CameraEED2Ev:
  398|  6.79k|inline LazyDict<T>::~LazyDict() {
  399|  6.79k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 0, False: 6.79k]
  ------------------
  400|      0|        delete mObjs[i];
  401|      0|    }
  402|  6.79k|}
_ZN5glTF28LazyDictINS_10BufferViewEED2Ev:
  398|  6.79k|inline LazyDict<T>::~LazyDict() {
  399|  13.4k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 6.66k, False: 6.79k]
  ------------------
  400|  6.66k|        delete mObjs[i];
  401|  6.66k|    }
  402|  6.79k|}
_ZN5glTF28LazyDictINS_6BufferEED2Ev:
  398|  6.79k|inline LazyDict<T>::~LazyDict() {
  399|  11.2k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 4.48k, False: 6.79k]
  ------------------
  400|  4.48k|        delete mObjs[i];
  401|  4.48k|    }
  402|  6.79k|}
_ZN5glTF28LazyDictINS_9AnimationEED2Ev:
  398|  6.79k|inline LazyDict<T>::~LazyDict() {
  399|  6.79k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 0, False: 6.79k]
  ------------------
  400|      0|        delete mObjs[i];
  401|      0|    }
  402|  6.79k|}
_ZN5glTF28LazyDictINS_8AccessorEED2Ev:
  398|  6.79k|inline LazyDict<T>::~LazyDict() {
  399|  13.7k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 6.95k, False: 6.79k]
  ------------------
  400|  6.95k|        delete mObjs[i];
  401|  6.95k|    }
  402|  6.79k|}
_ZN5glTF26BufferC2Ev:
  558|  4.48k|        byteLength(0),
  559|  4.48k|        type(Type_arraybuffer),
  560|  4.48k|        EncodedRegion_Current(nullptr),
  561|  4.48k|        mIsSpecial(false) {
  562|       |    // empty
  563|  4.48k|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_19SetVectorERA4_fRA4_Kf:
  176|  8.62k|void SetVector(vec4 &v, const float (&in)[4]) {
  177|  8.62k|    v[0] = in[0];
  178|  8.62k|    v[1] = in[1];
  179|  8.62k|    v[2] = in[2];
  180|  8.62k|    v[3] = in[3];
  181|  8.62k|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_19SetVectorERA3_fRA3_Kf:
  183|  19.2k|void SetVector(vec3 &v, const float (&in)[3]) {
  184|  19.2k|    v[0] = in[0];
  185|  19.2k|    v[1] = in[1];
  186|  19.2k|    v[2] = in[2];
  187|  19.2k|}
_ZN5glTF28Accessor7IndexerC2ERS0_:
 1115|  1.04k|    accessor(acc),
 1116|  1.04k|    data(acc.GetPointer()),
 1117|  1.04k|    elemSize(acc.GetElementSize()),
 1118|  1.04k|    stride(acc.GetStride()) {
 1119|  1.04k|}
glTF2Importer.cpp:_ZN5glTF28Accessor11ExtractDataIZL24BuildVertexWeightMappingRNS_4Mesh9PrimitiveERNSt3__16vectorINS6_I14aiVertexWeightNS5_9allocatorIS7_EEEENS8_ISA_EEEEPNS6_IjNS8_IjEEEEE7WeightsEEmRPT_PKSF_:
 1021|    731|size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
 1022|    731|    uint8_t *data = GetPointer();
 1023|    731|    if (!data) {
  ------------------
  |  Branch (1023:9): [True: 5, False: 726]
  ------------------
 1024|      5|        throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
 1025|      5|    }
 1026|       |
 1027|    726|    const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
  ------------------
  |  Branch (1027:30): [True: 565, False: 161]
  ------------------
 1028|    726|    const size_t elemSize = GetElementSize();
 1029|    726|    const size_t totalSize = elemSize * usedCount;
 1030|       |
 1031|    726|    const size_t stride = GetStride();
 1032|       |
 1033|    726|    const size_t targetElemSize = sizeof(T);
 1034|       |
 1035|    726|    if (elemSize > targetElemSize) {
  ------------------
  |  Branch (1035:9): [True: 1, False: 725]
  ------------------
 1036|      1|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > targetElemSize ", targetElemSize, " in ", getContextForErrorMessages(id, name));
 1037|      1|    }
 1038|       |
 1039|    725|    const size_t maxSize = GetMaxByteSize();
 1040|       |
 1041|    725|    if (elemSize > maxSize) {
  ------------------
  |  Branch (1041:9): [True: 1, False: 724]
  ------------------
 1042|      1|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1043|      1|    }
 1044|       |
 1045|    724|    const size_t maxCount = (maxSize - elemSize) / stride + 1;
 1046|       |
 1047|    724|    if (count > maxCount) {
  ------------------
  |  Branch (1047:9): [True: 0, False: 724]
  ------------------
 1048|      0|        throw DeadlyImportError("GLTF: count ", count, " > maxCount ", maxCount, " in ", getContextForErrorMessages(id, name));
 1049|      0|    }
 1050|       |
 1051|    724|    outData = new T[usedCount];
 1052|       |
 1053|    724|    if (remappingIndices != nullptr) {
  ------------------
  |  Branch (1053:9): [True: 564, False: 160]
  ------------------
 1054|  2.48k|        for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1054:28): [True: 1.92k, False: 563]
  ------------------
 1055|  1.92k|            size_t srcIdx = (*remappingIndices)[i];
 1056|  1.92k|            if (srcIdx >= count) {
  ------------------
  |  Branch (1056:17): [True: 1, False: 1.92k]
  ------------------
 1057|      1|                throw DeadlyImportError("GLTF: index ", srcIdx, " >= count ", count, " in ", getContextForErrorMessages(id, name));
 1058|      1|            }
 1059|  1.92k|            memcpy(outData + i, data + srcIdx * stride, elemSize);
 1060|  1.92k|        }
 1061|    564|    } else { // non-indexed cases
 1062|    160|        if (stride == elemSize && targetElemSize == elemSize) {
  ------------------
  |  Branch (1062:13): [True: 160, False: 0]
  |  Branch (1062:35): [True: 120, False: 40]
  ------------------
 1063|    120|            memcpy(outData, data, totalSize);
 1064|    120|        } else {
 1065|    188|            for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1065:32): [True: 148, False: 40]
  ------------------
 1066|    148|                memcpy(outData + i, data + i * stride, elemSize);
 1067|    148|            }
 1068|     40|        }
 1069|    160|    }
 1070|    723|    return usedCount;
 1071|    724|}
glTF2Importer.cpp:_ZN5glTF28Accessor11ExtractDataIZL24BuildVertexWeightMappingRNS_4Mesh9PrimitiveERNSt3__16vectorINS6_I14aiVertexWeightNS5_9allocatorIS7_EEEENS8_ISA_EEEEPNS6_IjNS8_IjEEEEE8Indices8EEmRPT_PKSF_:
 1021|     76|size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
 1022|     76|    uint8_t *data = GetPointer();
 1023|     76|    if (!data) {
  ------------------
  |  Branch (1023:9): [True: 10, False: 66]
  ------------------
 1024|     10|        throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
 1025|     10|    }
 1026|       |
 1027|     66|    const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
  ------------------
  |  Branch (1027:30): [True: 27, False: 39]
  ------------------
 1028|     66|    const size_t elemSize = GetElementSize();
 1029|     66|    const size_t totalSize = elemSize * usedCount;
 1030|       |
 1031|     66|    const size_t stride = GetStride();
 1032|       |
 1033|     66|    const size_t targetElemSize = sizeof(T);
 1034|       |
 1035|     66|    if (elemSize > targetElemSize) {
  ------------------
  |  Branch (1035:9): [True: 11, False: 55]
  ------------------
 1036|     11|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > targetElemSize ", targetElemSize, " in ", getContextForErrorMessages(id, name));
 1037|     11|    }
 1038|       |
 1039|     55|    const size_t maxSize = GetMaxByteSize();
 1040|       |
 1041|     55|    if (elemSize > maxSize) {
  ------------------
  |  Branch (1041:9): [True: 0, False: 55]
  ------------------
 1042|      0|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1043|      0|    }
 1044|       |
 1045|     55|    const size_t maxCount = (maxSize - elemSize) / stride + 1;
 1046|       |
 1047|     55|    if (count > maxCount) {
  ------------------
  |  Branch (1047:9): [True: 0, False: 55]
  ------------------
 1048|      0|        throw DeadlyImportError("GLTF: count ", count, " > maxCount ", maxCount, " in ", getContextForErrorMessages(id, name));
 1049|      0|    }
 1050|       |
 1051|     55|    outData = new T[usedCount];
 1052|       |
 1053|     55|    if (remappingIndices != nullptr) {
  ------------------
  |  Branch (1053:9): [True: 19, False: 36]
  ------------------
 1054|     78|        for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1054:28): [True: 59, False: 19]
  ------------------
 1055|     59|            size_t srcIdx = (*remappingIndices)[i];
 1056|     59|            if (srcIdx >= count) {
  ------------------
  |  Branch (1056:17): [True: 0, False: 59]
  ------------------
 1057|      0|                throw DeadlyImportError("GLTF: index ", srcIdx, " >= count ", count, " in ", getContextForErrorMessages(id, name));
 1058|      0|            }
 1059|     59|            memcpy(outData + i, data + srcIdx * stride, elemSize);
 1060|     59|        }
 1061|     36|    } else { // non-indexed cases
 1062|     36|        if (stride == elemSize && targetElemSize == elemSize) {
  ------------------
  |  Branch (1062:13): [True: 36, False: 0]
  |  Branch (1062:35): [True: 24, False: 12]
  ------------------
 1063|     24|            memcpy(outData, data, totalSize);
 1064|     24|        } else {
 1065|     66|            for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1065:32): [True: 54, False: 12]
  ------------------
 1066|     54|                memcpy(outData + i, data + i * stride, elemSize);
 1067|     54|            }
 1068|     12|        }
 1069|     36|    }
 1070|     55|    return usedCount;
 1071|     55|}
glTF2Importer.cpp:_ZN5glTF28Accessor11ExtractDataIZL24BuildVertexWeightMappingRNS_4Mesh9PrimitiveERNSt3__16vectorINS6_I14aiVertexWeightNS5_9allocatorIS7_EEEENS8_ISA_EEEEPNS6_IjNS8_IjEEEEE9Indices16EEmRPT_PKSF_:
 1021|    612|size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
 1022|    612|    uint8_t *data = GetPointer();
 1023|    612|    if (!data) {
  ------------------
  |  Branch (1023:9): [True: 6, False: 606]
  ------------------
 1024|      6|        throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
 1025|      6|    }
 1026|       |
 1027|    606|    const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
  ------------------
  |  Branch (1027:30): [True: 510, False: 96]
  ------------------
 1028|    606|    const size_t elemSize = GetElementSize();
 1029|    606|    const size_t totalSize = elemSize * usedCount;
 1030|       |
 1031|    606|    const size_t stride = GetStride();
 1032|       |
 1033|    606|    const size_t targetElemSize = sizeof(T);
 1034|       |
 1035|    606|    if (elemSize > targetElemSize) {
  ------------------
  |  Branch (1035:9): [True: 3, False: 603]
  ------------------
 1036|      3|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > targetElemSize ", targetElemSize, " in ", getContextForErrorMessages(id, name));
 1037|      3|    }
 1038|       |
 1039|    603|    const size_t maxSize = GetMaxByteSize();
 1040|       |
 1041|    603|    if (elemSize > maxSize) {
  ------------------
  |  Branch (1041:9): [True: 0, False: 603]
  ------------------
 1042|      0|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1043|      0|    }
 1044|       |
 1045|    603|    const size_t maxCount = (maxSize - elemSize) / stride + 1;
 1046|       |
 1047|    603|    if (count > maxCount) {
  ------------------
  |  Branch (1047:9): [True: 0, False: 603]
  ------------------
 1048|      0|        throw DeadlyImportError("GLTF: count ", count, " > maxCount ", maxCount, " in ", getContextForErrorMessages(id, name));
 1049|      0|    }
 1050|       |
 1051|    603|    outData = new T[usedCount];
 1052|       |
 1053|    603|    if (remappingIndices != nullptr) {
  ------------------
  |  Branch (1053:9): [True: 508, False: 95]
  ------------------
 1054|  2.23k|        for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1054:28): [True: 1.72k, False: 507]
  ------------------
 1055|  1.72k|            size_t srcIdx = (*remappingIndices)[i];
 1056|  1.72k|            if (srcIdx >= count) {
  ------------------
  |  Branch (1056:17): [True: 1, False: 1.72k]
  ------------------
 1057|      1|                throw DeadlyImportError("GLTF: index ", srcIdx, " >= count ", count, " in ", getContextForErrorMessages(id, name));
 1058|      1|            }
 1059|  1.72k|            memcpy(outData + i, data + srcIdx * stride, elemSize);
 1060|  1.72k|        }
 1061|    508|    } else { // non-indexed cases
 1062|     95|        if (stride == elemSize && targetElemSize == elemSize) {
  ------------------
  |  Branch (1062:13): [True: 95, False: 0]
  |  Branch (1062:35): [True: 69, False: 26]
  ------------------
 1063|     69|            memcpy(outData, data, totalSize);
 1064|     69|        } else {
 1065|    150|            for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1065:32): [True: 124, False: 26]
  ------------------
 1066|    124|                memcpy(outData + i, data + i * stride, elemSize);
 1067|    124|            }
 1068|     26|        }
 1069|     95|    }
 1070|    602|    return usedCount;
 1071|    603|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_114ReadExtensionsEPKcRN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEE:
  110|  30.5k|inline CustomExtension ReadExtensions(const char *name, Value &obj) {
  111|  30.5k|    CustomExtension ret;
  112|  30.5k|    ret.name = name;
  113|  30.5k|    if (obj.IsObject()) {
  ------------------
  |  Branch (113:9): [True: 18, False: 30.5k]
  ------------------
  114|     18|        ret.mValues.isPresent = true;
  115|     96|        for (auto it = obj.MemberBegin(); it != obj.MemberEnd(); ++it) {
  ------------------
  |  Branch (115:43): [True: 78, False: 18]
  ------------------
  116|     78|            auto &val = it->value;
  117|     78|            ret.mValues.value.push_back(ReadExtensions(it->name.GetString(), val));
  118|     78|        }
  119|  30.5k|    } else if (obj.IsArray()) {
  ------------------
  |  Branch (119:16): [True: 35, False: 30.5k]
  ------------------
  120|     35|        ret.mValues.value.reserve(obj.Size());
  121|     35|        ret.mValues.isPresent = true;
  122|     81|        for (unsigned int i = 0; i < obj.Size(); ++i) {
  ------------------
  |  Branch (122:34): [True: 46, False: 35]
  ------------------
  123|     46|            ret.mValues.value.push_back(ReadExtensions(name, obj[i]));
  124|     46|        }
  125|  30.5k|    } else if (obj.IsNumber()) {
  ------------------
  |  Branch (125:16): [True: 15.5k, False: 15.0k]
  ------------------
  126|  15.5k|        if (obj.IsUint64()) {
  ------------------
  |  Branch (126:13): [True: 15.4k, False: 22]
  ------------------
  127|  15.4k|            ret.mUint64Value.value = obj.GetUint64();
  128|  15.4k|            ret.mUint64Value.isPresent = true;
  129|  15.4k|        } else if (obj.IsInt64()) {
  ------------------
  |  Branch (129:20): [True: 6, False: 16]
  ------------------
  130|      6|            ret.mInt64Value.value = obj.GetInt64();
  131|      6|            ret.mInt64Value.isPresent = true;
  132|     16|        } else if (obj.IsDouble()) {
  ------------------
  |  Branch (132:20): [True: 16, False: 0]
  ------------------
  133|     16|            ret.mDoubleValue.value = obj.GetDouble();
  134|     16|            ret.mDoubleValue.isPresent = true;
  135|     16|        }
  136|  15.5k|    } else if (obj.IsString()) {
  ------------------
  |  Branch (136:16): [True: 7.50k, False: 7.50k]
  ------------------
  137|  7.50k|        ReadValue(obj, ret.mStringValue);
  138|  7.50k|        ret.mStringValue.isPresent = true;
  139|  7.50k|    } else if (obj.IsBool()) {
  ------------------
  |  Branch (139:16): [True: 7.50k, False: 0]
  ------------------
  140|  7.50k|        ret.mBoolValue.value = obj.GetBool();
  141|  7.50k|        ret.mBoolValue.isPresent = true;
  142|  7.50k|    }
  143|  30.5k|    return ret;
  144|  30.5k|}
_ZN5glTF25ImageC2Ev:
 1137|     60|        width(0),
 1138|     60|        height(0),
 1139|     60|        mDataLength(0) {
 1140|     60|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_115GetAttribVectorERNS_4Mesh9PrimitiveEPKcRPNSt3__16vectorIN10glTFCommon3RefINS_8AccessorEEENS6_9allocatorISB_EEEERi:
  199|  6.44k|inline bool GetAttribVector(Mesh::Primitive &p, const char *attr, Mesh::AccessorList *&v, int &pos) {
  200|  6.44k|    if ((pos = Compare(attr, "POSITION"))) {
  ------------------
  |  Branch (200:9): [True: 1.73k, False: 4.71k]
  ------------------
  201|  1.73k|        v = &(p.attributes.position);
  202|  4.71k|    } else if ((pos = Compare(attr, "NORMAL"))) {
  ------------------
  |  Branch (202:16): [True: 1.32k, False: 3.39k]
  ------------------
  203|  1.32k|        v = &(p.attributes.normal);
  204|  3.39k|    } else if ((pos = Compare(attr, "TANGENT"))) {
  ------------------
  |  Branch (204:16): [True: 58, False: 3.33k]
  ------------------
  205|     58|        v = &(p.attributes.tangent);
  206|  3.33k|    } else if ((pos = Compare(attr, "TEXCOORD"))) {
  ------------------
  |  Branch (206:16): [True: 530, False: 2.80k]
  ------------------
  207|    530|        v = &(p.attributes.texcoord);
  208|  2.80k|    } else if ((pos = Compare(attr, "COLOR"))) {
  ------------------
  |  Branch (208:16): [True: 373, False: 2.42k]
  ------------------
  209|    373|        v = &(p.attributes.color);
  210|  2.42k|    } else if ((pos = Compare(attr, "JOINTS"))) {
  ------------------
  |  Branch (210:16): [True: 953, False: 1.47k]
  ------------------
  211|    953|        v = &(p.attributes.joint);
  212|  1.47k|    } else if ((pos = Compare(attr, "JOINTMATRIX"))) {
  ------------------
  |  Branch (212:16): [True: 0, False: 1.47k]
  ------------------
  213|      0|        v = &(p.attributes.jointmatrix);
  214|  1.47k|    } else if ((pos = Compare(attr, "WEIGHTS"))) {
  ------------------
  |  Branch (214:16): [True: 925, False: 551]
  ------------------
  215|    925|        v = &(p.attributes.weight);
  216|    925|    } else
  217|    551|        return false;
  218|  5.89k|    return true;
  219|  6.44k|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_17CompareILi9EEEiPKcRAT__S2_:
  190|  9.77k|inline int Compare(const char *attr, const char (&str)[N]) {
  191|  9.77k|    return (strncmp(attr, str, N - 1) == 0) ? N - 1 : 0;
  ------------------
  |  Branch (191:12): [True: 2.26k, False: 7.51k]
  ------------------
  192|  9.77k|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_17CompareILi7EEEiPKcRAT__S2_:
  190|  7.14k|inline int Compare(const char *attr, const char (&str)[N]) {
  191|  7.14k|    return (strncmp(attr, str, N - 1) == 0) ? N - 1 : 0;
  ------------------
  |  Branch (191:12): [True: 2.27k, False: 4.86k]
  ------------------
  192|  7.14k|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_17CompareILi8EEEiPKcRAT__S2_:
  190|  4.86k|inline int Compare(const char *attr, const char (&str)[N]) {
  191|  4.86k|    return (strncmp(attr, str, N - 1) == 0) ? N - 1 : 0;
  ------------------
  |  Branch (191:12): [True: 983, False: 3.88k]
  ------------------
  192|  4.86k|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_17CompareILi6EEEiPKcRAT__S2_:
  190|  2.80k|inline int Compare(const char *attr, const char (&str)[N]) {
  191|  2.80k|    return (strncmp(attr, str, N - 1) == 0) ? N - 1 : 0;
  ------------------
  |  Branch (191:12): [True: 373, False: 2.42k]
  ------------------
  192|  2.80k|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_17CompareILi12EEEiPKcRAT__S2_:
  190|  1.47k|inline int Compare(const char *attr, const char (&str)[N]) {
  191|  1.47k|    return (strncmp(attr, str, N - 1) == 0) ? N - 1 : 0;
  ------------------
  |  Branch (191:12): [True: 0, False: 1.47k]
  ------------------
  192|  1.47k|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_110ReadExtrasERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEE:
  146|  7.56k|inline Extras ReadExtras(Value &obj) {
  147|  7.56k|    Extras ret;
  148|       |
  149|  7.56k|    ret.mValues.reserve(obj.MemberCount());
  150|  38.0k|    for (auto it = obj.MemberBegin(); it != obj.MemberEnd(); ++it) {
  ------------------
  |  Branch (150:39): [True: 30.4k, False: 7.56k]
  ------------------
  151|  30.4k|        auto &val = it->value;
  152|  30.4k|        ret.mValues.emplace_back(ReadExtensions(it->name.GetString(), val));
  153|  30.4k|    }
  154|       |
  155|  7.56k|    return ret;
  156|  7.56k|}
_ZN5glTF28Accessor11ExtractDataI10aiVector3tIfEEEmRPT_PKNSt3__16vectorIjNS7_9allocatorIjEEEE:
 1021|  2.97k|size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
 1022|  2.97k|    uint8_t *data = GetPointer();
 1023|  2.97k|    if (!data) {
  ------------------
  |  Branch (1023:9): [True: 13, False: 2.95k]
  ------------------
 1024|     13|        throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
 1025|     13|    }
 1026|       |
 1027|  2.95k|    const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
  ------------------
  |  Branch (1027:30): [True: 2.06k, False: 897]
  ------------------
 1028|  2.95k|    const size_t elemSize = GetElementSize();
 1029|  2.95k|    const size_t totalSize = elemSize * usedCount;
 1030|       |
 1031|  2.95k|    const size_t stride = GetStride();
 1032|       |
 1033|  2.95k|    const size_t targetElemSize = sizeof(T);
 1034|       |
 1035|  2.95k|    if (elemSize > targetElemSize) {
  ------------------
  |  Branch (1035:9): [True: 2, False: 2.95k]
  ------------------
 1036|      2|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > targetElemSize ", targetElemSize, " in ", getContextForErrorMessages(id, name));
 1037|      2|    }
 1038|       |
 1039|  2.95k|    const size_t maxSize = GetMaxByteSize();
 1040|       |
 1041|  2.95k|    if (elemSize > maxSize) {
  ------------------
  |  Branch (1041:9): [True: 1, False: 2.95k]
  ------------------
 1042|      1|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1043|      1|    }
 1044|       |
 1045|  2.95k|    const size_t maxCount = (maxSize - elemSize) / stride + 1;
 1046|       |
 1047|  2.95k|    if (count > maxCount) {
  ------------------
  |  Branch (1047:9): [True: 0, False: 2.95k]
  ------------------
 1048|      0|        throw DeadlyImportError("GLTF: count ", count, " > maxCount ", maxCount, " in ", getContextForErrorMessages(id, name));
 1049|      0|    }
 1050|       |
 1051|  2.95k|    outData = new T[usedCount];
 1052|       |
 1053|  2.95k|    if (remappingIndices != nullptr) {
  ------------------
  |  Branch (1053:9): [True: 2.05k, False: 896]
  ------------------
 1054|  16.9k|        for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1054:28): [True: 14.9k, False: 2.05k]
  ------------------
 1055|  14.9k|            size_t srcIdx = (*remappingIndices)[i];
 1056|  14.9k|            if (srcIdx >= count) {
  ------------------
  |  Branch (1056:17): [True: 0, False: 14.9k]
  ------------------
 1057|      0|                throw DeadlyImportError("GLTF: index ", srcIdx, " >= count ", count, " in ", getContextForErrorMessages(id, name));
 1058|      0|            }
 1059|  14.9k|            memcpy(outData + i, data + srcIdx * stride, elemSize);
 1060|  14.9k|        }
 1061|  2.05k|    } else { // non-indexed cases
 1062|    896|        if (stride == elemSize && targetElemSize == elemSize) {
  ------------------
  |  Branch (1062:13): [True: 709, False: 187]
  |  Branch (1062:35): [True: 252, False: 457]
  ------------------
 1063|    252|            memcpy(outData, data, totalSize);
 1064|    644|        } else {
 1065|  31.3k|            for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1065:32): [True: 30.6k, False: 644]
  ------------------
 1066|  30.6k|                memcpy(outData + i, data + i * stride, elemSize);
 1067|  30.6k|            }
 1068|    644|        }
 1069|    896|    }
 1070|  2.95k|    return usedCount;
 1071|  2.95k|}
glTF2Importer.cpp:_ZN5glTF28Accessor11ExtractDataIN12_GLOBAL__N_17TangentEEEmRPT_PKNSt3__16vectorIjNS7_9allocatorIjEEEE:
 1021|     40|size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
 1022|     40|    uint8_t *data = GetPointer();
 1023|     40|    if (!data) {
  ------------------
  |  Branch (1023:9): [True: 1, False: 39]
  ------------------
 1024|      1|        throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
 1025|      1|    }
 1026|       |
 1027|     39|    const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
  ------------------
  |  Branch (1027:30): [True: 27, False: 12]
  ------------------
 1028|     39|    const size_t elemSize = GetElementSize();
 1029|     39|    const size_t totalSize = elemSize * usedCount;
 1030|       |
 1031|     39|    const size_t stride = GetStride();
 1032|       |
 1033|     39|    const size_t targetElemSize = sizeof(T);
 1034|       |
 1035|     39|    if (elemSize > targetElemSize) {
  ------------------
  |  Branch (1035:9): [True: 0, False: 39]
  ------------------
 1036|      0|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > targetElemSize ", targetElemSize, " in ", getContextForErrorMessages(id, name));
 1037|      0|    }
 1038|       |
 1039|     39|    const size_t maxSize = GetMaxByteSize();
 1040|       |
 1041|     39|    if (elemSize > maxSize) {
  ------------------
  |  Branch (1041:9): [True: 0, False: 39]
  ------------------
 1042|      0|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1043|      0|    }
 1044|       |
 1045|     39|    const size_t maxCount = (maxSize - elemSize) / stride + 1;
 1046|       |
 1047|     39|    if (count > maxCount) {
  ------------------
  |  Branch (1047:9): [True: 0, False: 39]
  ------------------
 1048|      0|        throw DeadlyImportError("GLTF: count ", count, " > maxCount ", maxCount, " in ", getContextForErrorMessages(id, name));
 1049|      0|    }
 1050|       |
 1051|     39|    outData = new T[usedCount];
 1052|       |
 1053|     39|    if (remappingIndices != nullptr) {
  ------------------
  |  Branch (1053:9): [True: 27, False: 12]
  ------------------
 1054|    188|        for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1054:28): [True: 161, False: 27]
  ------------------
 1055|    161|            size_t srcIdx = (*remappingIndices)[i];
 1056|    161|            if (srcIdx >= count) {
  ------------------
  |  Branch (1056:17): [True: 0, False: 161]
  ------------------
 1057|      0|                throw DeadlyImportError("GLTF: index ", srcIdx, " >= count ", count, " in ", getContextForErrorMessages(id, name));
 1058|      0|            }
 1059|    161|            memcpy(outData + i, data + srcIdx * stride, elemSize);
 1060|    161|        }
 1061|     27|    } else { // non-indexed cases
 1062|     12|        if (stride == elemSize && targetElemSize == elemSize) {
  ------------------
  |  Branch (1062:13): [True: 9, False: 3]
  |  Branch (1062:35): [True: 2, False: 7]
  ------------------
 1063|      2|            memcpy(outData, data, totalSize);
 1064|     10|        } else {
 1065|    250|            for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1065:32): [True: 240, False: 10]
  ------------------
 1066|    240|                memcpy(outData + i, data + i * stride, elemSize);
 1067|    240|            }
 1068|     10|        }
 1069|     12|    }
 1070|     39|    return usedCount;
 1071|     39|}
_ZN5glTF28Accessor11ExtractDataI9aiColor4tIfEEEmRPT_PKNSt3__16vectorIjNS7_9allocatorIjEEEE:
 1021|    254|size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
 1022|    254|    uint8_t *data = GetPointer();
 1023|    254|    if (!data) {
  ------------------
  |  Branch (1023:9): [True: 3, False: 251]
  ------------------
 1024|      3|        throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
 1025|      3|    }
 1026|       |
 1027|    251|    const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
  ------------------
  |  Branch (1027:30): [True: 198, False: 53]
  ------------------
 1028|    251|    const size_t elemSize = GetElementSize();
 1029|    251|    const size_t totalSize = elemSize * usedCount;
 1030|       |
 1031|    251|    const size_t stride = GetStride();
 1032|       |
 1033|    251|    const size_t targetElemSize = sizeof(T);
 1034|       |
 1035|    251|    if (elemSize > targetElemSize) {
  ------------------
  |  Branch (1035:9): [True: 0, False: 251]
  ------------------
 1036|      0|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > targetElemSize ", targetElemSize, " in ", getContextForErrorMessages(id, name));
 1037|      0|    }
 1038|       |
 1039|    251|    const size_t maxSize = GetMaxByteSize();
 1040|       |
 1041|    251|    if (elemSize > maxSize) {
  ------------------
  |  Branch (1041:9): [True: 0, False: 251]
  ------------------
 1042|      0|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1043|      0|    }
 1044|       |
 1045|    251|    const size_t maxCount = (maxSize - elemSize) / stride + 1;
 1046|       |
 1047|    251|    if (count > maxCount) {
  ------------------
  |  Branch (1047:9): [True: 0, False: 251]
  ------------------
 1048|      0|        throw DeadlyImportError("GLTF: count ", count, " > maxCount ", maxCount, " in ", getContextForErrorMessages(id, name));
 1049|      0|    }
 1050|       |
 1051|    251|    outData = new T[usedCount];
 1052|       |
 1053|    251|    if (remappingIndices != nullptr) {
  ------------------
  |  Branch (1053:9): [True: 198, False: 53]
  ------------------
 1054|    891|        for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1054:28): [True: 693, False: 198]
  ------------------
 1055|    693|            size_t srcIdx = (*remappingIndices)[i];
 1056|    693|            if (srcIdx >= count) {
  ------------------
  |  Branch (1056:17): [True: 0, False: 693]
  ------------------
 1057|      0|                throw DeadlyImportError("GLTF: index ", srcIdx, " >= count ", count, " in ", getContextForErrorMessages(id, name));
 1058|      0|            }
 1059|    693|            memcpy(outData + i, data + srcIdx * stride, elemSize);
 1060|    693|        }
 1061|    198|    } else { // non-indexed cases
 1062|     53|        if (stride == elemSize && targetElemSize == elemSize) {
  ------------------
  |  Branch (1062:13): [True: 44, False: 9]
  |  Branch (1062:35): [True: 33, False: 11]
  ------------------
 1063|     33|            memcpy(outData, data, totalSize);
 1064|     33|        } else {
 1065|    420|            for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1065:32): [True: 400, False: 20]
  ------------------
 1066|    400|                memcpy(outData + i, data + i * stride, elemSize);
 1067|    400|            }
 1068|     20|        }
 1069|     53|    }
 1070|    251|    return usedCount;
 1071|    251|}
_ZN5glTF28Accessor11ExtractDataI9aiColor4tIhEEEmRPT_PKNSt3__16vectorIjNS7_9allocatorIjEEEE:
 1021|      7|size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
 1022|      7|    uint8_t *data = GetPointer();
 1023|      7|    if (!data) {
  ------------------
  |  Branch (1023:9): [True: 1, False: 6]
  ------------------
 1024|      1|        throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
 1025|      1|    }
 1026|       |
 1027|      6|    const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
  ------------------
  |  Branch (1027:30): [True: 4, False: 2]
  ------------------
 1028|      6|    const size_t elemSize = GetElementSize();
 1029|      6|    const size_t totalSize = elemSize * usedCount;
 1030|       |
 1031|      6|    const size_t stride = GetStride();
 1032|       |
 1033|      6|    const size_t targetElemSize = sizeof(T);
 1034|       |
 1035|      6|    if (elemSize > targetElemSize) {
  ------------------
  |  Branch (1035:9): [True: 0, False: 6]
  ------------------
 1036|      0|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > targetElemSize ", targetElemSize, " in ", getContextForErrorMessages(id, name));
 1037|      0|    }
 1038|       |
 1039|      6|    const size_t maxSize = GetMaxByteSize();
 1040|       |
 1041|      6|    if (elemSize > maxSize) {
  ------------------
  |  Branch (1041:9): [True: 0, False: 6]
  ------------------
 1042|      0|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1043|      0|    }
 1044|       |
 1045|      6|    const size_t maxCount = (maxSize - elemSize) / stride + 1;
 1046|       |
 1047|      6|    if (count > maxCount) {
  ------------------
  |  Branch (1047:9): [True: 0, False: 6]
  ------------------
 1048|      0|        throw DeadlyImportError("GLTF: count ", count, " > maxCount ", maxCount, " in ", getContextForErrorMessages(id, name));
 1049|      0|    }
 1050|       |
 1051|      6|    outData = new T[usedCount];
 1052|       |
 1053|      6|    if (remappingIndices != nullptr) {
  ------------------
  |  Branch (1053:9): [True: 4, False: 2]
  ------------------
 1054|     13|        for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1054:28): [True: 9, False: 4]
  ------------------
 1055|      9|            size_t srcIdx = (*remappingIndices)[i];
 1056|      9|            if (srcIdx >= count) {
  ------------------
  |  Branch (1056:17): [True: 0, False: 9]
  ------------------
 1057|      0|                throw DeadlyImportError("GLTF: index ", srcIdx, " >= count ", count, " in ", getContextForErrorMessages(id, name));
 1058|      0|            }
 1059|      9|            memcpy(outData + i, data + srcIdx * stride, elemSize);
 1060|      9|        }
 1061|      4|    } else { // non-indexed cases
 1062|      2|        if (stride == elemSize && targetElemSize == elemSize) {
  ------------------
  |  Branch (1062:13): [True: 2, False: 0]
  |  Branch (1062:35): [True: 1, False: 1]
  ------------------
 1063|      1|            memcpy(outData, data, totalSize);
 1064|      1|        } else {
 1065|      5|            for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1065:32): [True: 4, False: 1]
  ------------------
 1066|      4|                memcpy(outData + i, data + i * stride, elemSize);
 1067|      4|            }
 1068|      1|        }
 1069|      2|    }
 1070|      6|    return usedCount;
 1071|      6|}
_ZN5glTF28Accessor11ExtractDataI9aiColor4tItEEEmRPT_PKNSt3__16vectorIjNS7_9allocatorIjEEEE:
 1021|      8|size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
 1022|      8|    uint8_t *data = GetPointer();
 1023|      8|    if (!data) {
  ------------------
  |  Branch (1023:9): [True: 1, False: 7]
  ------------------
 1024|      1|        throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
 1025|      1|    }
 1026|       |
 1027|      7|    const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
  ------------------
  |  Branch (1027:30): [True: 5, False: 2]
  ------------------
 1028|      7|    const size_t elemSize = GetElementSize();
 1029|      7|    const size_t totalSize = elemSize * usedCount;
 1030|       |
 1031|      7|    const size_t stride = GetStride();
 1032|       |
 1033|      7|    const size_t targetElemSize = sizeof(T);
 1034|       |
 1035|      7|    if (elemSize > targetElemSize) {
  ------------------
  |  Branch (1035:9): [True: 0, False: 7]
  ------------------
 1036|      0|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > targetElemSize ", targetElemSize, " in ", getContextForErrorMessages(id, name));
 1037|      0|    }
 1038|       |
 1039|      7|    const size_t maxSize = GetMaxByteSize();
 1040|       |
 1041|      7|    if (elemSize > maxSize) {
  ------------------
  |  Branch (1041:9): [True: 0, False: 7]
  ------------------
 1042|      0|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1043|      0|    }
 1044|       |
 1045|      7|    const size_t maxCount = (maxSize - elemSize) / stride + 1;
 1046|       |
 1047|      7|    if (count > maxCount) {
  ------------------
  |  Branch (1047:9): [True: 0, False: 7]
  ------------------
 1048|      0|        throw DeadlyImportError("GLTF: count ", count, " > maxCount ", maxCount, " in ", getContextForErrorMessages(id, name));
 1049|      0|    }
 1050|       |
 1051|      7|    outData = new T[usedCount];
 1052|       |
 1053|      7|    if (remappingIndices != nullptr) {
  ------------------
  |  Branch (1053:9): [True: 5, False: 2]
  ------------------
 1054|     14|        for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1054:28): [True: 9, False: 5]
  ------------------
 1055|      9|            size_t srcIdx = (*remappingIndices)[i];
 1056|      9|            if (srcIdx >= count) {
  ------------------
  |  Branch (1056:17): [True: 0, False: 9]
  ------------------
 1057|      0|                throw DeadlyImportError("GLTF: index ", srcIdx, " >= count ", count, " in ", getContextForErrorMessages(id, name));
 1058|      0|            }
 1059|      9|            memcpy(outData + i, data + srcIdx * stride, elemSize);
 1060|      9|        }
 1061|      5|    } else { // non-indexed cases
 1062|      2|        if (stride == elemSize && targetElemSize == elemSize) {
  ------------------
  |  Branch (1062:13): [True: 2, False: 0]
  |  Branch (1062:35): [True: 1, False: 1]
  ------------------
 1063|      1|            memcpy(outData, data, totalSize);
 1064|      1|        } else {
 1065|      5|            for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1065:32): [True: 4, False: 1]
  ------------------
 1066|      4|                memcpy(outData + i, data + i * stride, elemSize);
 1067|      4|            }
 1068|      1|        }
 1069|      2|    }
 1070|      7|    return usedCount;
 1071|      7|}
_ZN5glTF28Accessor11ExtractDataIA16_fEEmRPT_PKNSt3__16vectorIjNS6_9allocatorIjEEEE:
 1021|    235|size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
 1022|    235|    uint8_t *data = GetPointer();
 1023|    235|    if (!data) {
  ------------------
  |  Branch (1023:9): [True: 6, False: 229]
  ------------------
 1024|      6|        throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
 1025|      6|    }
 1026|       |
 1027|    229|    const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
  ------------------
  |  Branch (1027:30): [True: 0, False: 229]
  ------------------
 1028|    229|    const size_t elemSize = GetElementSize();
 1029|    229|    const size_t totalSize = elemSize * usedCount;
 1030|       |
 1031|    229|    const size_t stride = GetStride();
 1032|       |
 1033|    229|    const size_t targetElemSize = sizeof(T);
 1034|       |
 1035|    229|    if (elemSize > targetElemSize) {
  ------------------
  |  Branch (1035:9): [True: 0, False: 229]
  ------------------
 1036|      0|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > targetElemSize ", targetElemSize, " in ", getContextForErrorMessages(id, name));
 1037|      0|    }
 1038|       |
 1039|    229|    const size_t maxSize = GetMaxByteSize();
 1040|       |
 1041|    229|    if (elemSize > maxSize) {
  ------------------
  |  Branch (1041:9): [True: 0, False: 229]
  ------------------
 1042|      0|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1043|      0|    }
 1044|       |
 1045|    229|    const size_t maxCount = (maxSize - elemSize) / stride + 1;
 1046|       |
 1047|    229|    if (count > maxCount) {
  ------------------
  |  Branch (1047:9): [True: 0, False: 229]
  ------------------
 1048|      0|        throw DeadlyImportError("GLTF: count ", count, " > maxCount ", maxCount, " in ", getContextForErrorMessages(id, name));
 1049|      0|    }
 1050|       |
 1051|    229|    outData = new T[usedCount];
 1052|       |
 1053|    229|    if (remappingIndices != nullptr) {
  ------------------
  |  Branch (1053:9): [True: 0, False: 229]
  ------------------
 1054|      0|        for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1054:28): [True: 0, False: 0]
  ------------------
 1055|      0|            size_t srcIdx = (*remappingIndices)[i];
 1056|      0|            if (srcIdx >= count) {
  ------------------
  |  Branch (1056:17): [True: 0, False: 0]
  ------------------
 1057|      0|                throw DeadlyImportError("GLTF: index ", srcIdx, " >= count ", count, " in ", getContextForErrorMessages(id, name));
 1058|      0|            }
 1059|      0|            memcpy(outData + i, data + srcIdx * stride, elemSize);
 1060|      0|        }
 1061|    229|    } else { // non-indexed cases
 1062|    229|        if (stride == elemSize && targetElemSize == elemSize) {
  ------------------
  |  Branch (1062:13): [True: 229, False: 0]
  |  Branch (1062:35): [True: 179, False: 50]
  ------------------
 1063|    179|            memcpy(outData, data, totalSize);
 1064|    179|        } else {
 1065|    570|            for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1065:32): [True: 520, False: 50]
  ------------------
 1066|    520|                memcpy(outData + i, data + i * stride, elemSize);
 1067|    520|            }
 1068|     50|        }
 1069|    229|    }
 1070|    229|    return usedCount;
 1071|    229|}

_ZN6Assimp13glTF2ImporterC2Ev:
  101|  3.48k|        mScene(nullptr) {
  102|       |    // empty
  103|  3.48k|}
_ZNK6Assimp13glTF2Importer7GetInfoEv:
  105|  12.7k|const aiImporterDesc *glTF2Importer::GetInfo() const {
  106|  12.7k|    return &desc;
  107|  12.7k|}
_ZNK6Assimp13glTF2Importer7CanReadERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEPNS_8IOSystemEb:
  109|  4.40k|bool glTF2Importer::CanRead(const std::string &filename, IOSystem *pIOHandler, bool checkSig) const {
  110|  4.40k|    const std::string extension = GetExtension(filename);
  111|  4.40k|    if (!checkSig && (extension != "gltf") && (extension != "glb") && (extension != "vrm")) {
  ------------------
  |  Branch (111:9): [True: 0, False: 4.40k]
  |  Branch (111:22): [True: 0, False: 0]
  |  Branch (111:47): [True: 0, False: 0]
  |  Branch (111:71): [True: 0, False: 0]
  ------------------
  112|      0|        return false;
  113|      0|    }
  114|       |
  115|  4.40k|    if (pIOHandler) {
  ------------------
  |  Branch (115:9): [True: 4.40k, False: 0]
  ------------------
  116|  4.40k|        Asset asset(pIOHandler);
  117|  4.40k|        return asset.CanRead(
  118|  4.40k|            filename,
  119|  4.40k|            CheckMagicToken(
  120|  4.40k|                pIOHandler, filename, AI_GLB_MAGIC_NUMBER, 1, 0,
  ------------------
  |  |  147|  4.40k|#define AI_GLB_MAGIC_NUMBER "glTF"
  ------------------
  121|  4.40k|                static_cast<unsigned int>(strlen(AI_GLB_MAGIC_NUMBER))));
  ------------------
  |  |  147|  4.40k|#define AI_GLB_MAGIC_NUMBER "glTF"
  ------------------
  122|  4.40k|    }
  123|       |
  124|      0|    return false;
  125|  4.40k|}
_ZN6Assimp13glTF2Importer15ImportMaterialsERN5glTF25AssetE:
  396|  2.00k|void glTF2Importer::ImportMaterials(Asset &r) {
  397|  2.00k|    const unsigned int numImportedMaterials = unsigned(r.materials.Size());
  398|  2.00k|    ASSIMP_LOG_DEBUG("Importing ", numImportedMaterials, " materials");
  399|  2.00k|    Material defaultMaterial;
  400|       |
  401|  2.00k|    mScene->mNumMaterials = numImportedMaterials + 1;
  402|  2.00k|    mScene->mMaterials = new aiMaterial *[mScene->mNumMaterials];
  403|  2.00k|    std::fill(mScene->mMaterials, mScene->mMaterials + mScene->mNumMaterials, nullptr);
  404|  2.00k|    mScene->mMaterials[numImportedMaterials] = ImportMaterial(mEmbeddedTexIdxs, r, defaultMaterial);
  405|       |
  406|  3.40k|    for (unsigned int i = 0; i < numImportedMaterials; ++i) {
  ------------------
  |  Branch (406:30): [True: 1.39k, False: 2.00k]
  ------------------
  407|  1.39k|        mScene->mMaterials[i] = ImportMaterial(mEmbeddedTexIdxs, r, r.materials[i]);
  408|  1.39k|    }
  409|  2.00k|}
_ZN6Assimp13glTF2Importer12ImportMeshesERN5glTF25AssetE:
  475|  2.00k|void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
  476|  2.00k|    ASSIMP_LOG_DEBUG("Importing ", r.meshes.Size(), " meshes");
  477|  2.00k|    std::vector<std::unique_ptr<aiMesh>> meshes;
  478|       |
  479|  2.00k|    meshOffsets.clear();
  480|  2.00k|    meshOffsets.reserve(r.meshes.Size() + 1);
  481|  2.00k|    mVertexRemappingTables.clear();
  482|       |
  483|       |    // Count the number of aiMeshes
  484|  2.00k|    unsigned int num_aiMeshes = 0;
  485|  3.75k|    for (unsigned int m = 0; m < r.meshes.Size(); ++m) {
  ------------------
  |  Branch (485:30): [True: 1.75k, False: 2.00k]
  ------------------
  486|  1.75k|        meshOffsets.push_back(num_aiMeshes);
  487|  1.75k|        num_aiMeshes += unsigned(r.meshes[m].primitives.size());
  488|  1.75k|    }
  489|  2.00k|    meshOffsets.push_back(num_aiMeshes); // add a last element so we can always do meshOffsets[n+1] - meshOffsets[n]
  490|       |
  491|  2.00k|    std::vector<unsigned int> reverseMappingIndices;
  492|  2.00k|    std::vector<unsigned int> indexBuffer;
  493|  2.00k|    meshes.reserve(num_aiMeshes);
  494|  2.00k|    mVertexRemappingTables.resize(num_aiMeshes);
  495|       |
  496|  3.46k|    for (unsigned int m = 0; m < r.meshes.Size(); ++m) {
  ------------------
  |  Branch (496:30): [True: 1.75k, False: 1.70k]
  ------------------
  497|  1.75k|        Mesh &mesh = r.meshes[m];
  498|       |
  499|  3.18k|        for (unsigned int p = 0; p < mesh.primitives.size(); ++p) {
  ------------------
  |  Branch (499:34): [True: 1.72k, False: 1.45k]
  ------------------
  500|  1.72k|            Mesh::Primitive &prim = mesh.primitives[p];
  501|       |
  502|  1.72k|            Mesh::Primitive::Attributes &attr = prim.attributes;
  503|       |
  504|       |            // Find out the maximum number of vertices:
  505|  1.72k|            size_t numAllVertices = 0;
  506|  1.72k|            if (!attr.position.empty() && attr.position[0]) {
  ------------------
  |  Branch (506:17): [True: 1.59k, False: 126]
  |  Branch (506:43): [True: 1.59k, False: 0]
  ------------------
  507|  1.59k|                numAllVertices = attr.position[0]->count;
  508|  1.59k|            }
  509|       |
  510|       |            // Extract used vertices:
  511|  1.72k|            bool useIndexBuffer = prim.indices;
  512|  1.72k|            std::vector<unsigned int> *vertexRemappingTable = nullptr;
  513|       |
  514|  1.72k|            if (useIndexBuffer) {
  ------------------
  |  Branch (514:17): [True: 1.04k, False: 679]
  ------------------
  515|  1.04k|                size_t count = prim.indices->count;
  516|  1.04k|                indexBuffer.resize(count);
  517|  1.04k|                reverseMappingIndices.clear();
  518|  1.04k|                vertexRemappingTable = &mVertexRemappingTables[meshes.size()];
  519|  1.04k|                vertexRemappingTable->reserve(count / 3); // this is a very rough heuristic to reduce re-allocations
  520|  1.04k|                Accessor::Indexer data = prim.indices->GetIndexer();
  521|  1.04k|                if (!data.IsValid()) {
  ------------------
  |  Branch (521:21): [True: 11, False: 1.03k]
  ------------------
  522|     11|                    throw DeadlyImportError("GLTF: Invalid accessor without data in mesh ", getContextForErrorMessages(mesh.id, mesh.name));
  523|     11|                }
  524|       |
  525|       |                // Build the vertex remapping table and the modified index buffer (used later instead of the original one)
  526|       |                // In case no index buffer is used, the original vertex arrays are being used so no remapping is required in the first place.
  527|  1.03k|                const unsigned int unusedIndex = ~0u;
  528|  30.9k|                for (unsigned int i = 0; i < count; ++i) {
  ------------------
  |  Branch (528:42): [True: 29.9k, False: 1.03k]
  ------------------
  529|  29.9k|                    unsigned int index = data.GetUInt(i);
  530|  29.9k|                    if (index >= numAllVertices) {
  ------------------
  |  Branch (530:25): [True: 14.1k, False: 15.7k]
  ------------------
  531|       |                        // Out-of-range indices will be filtered out when adding the faces and then lead to a warning. At this stage, we just keep them.
  532|  14.1k|                        indexBuffer[i] = index;
  533|  14.1k|                        continue;
  534|  14.1k|                    }
  535|  15.7k|                    if (index >= reverseMappingIndices.size()) {
  ------------------
  |  Branch (535:25): [True: 5.95k, False: 9.83k]
  ------------------
  536|  5.95k|                        reverseMappingIndices.resize(index + 1, unusedIndex);
  537|  5.95k|                    }
  538|  15.7k|                    if (reverseMappingIndices[index] == unusedIndex) {
  ------------------
  |  Branch (538:25): [True: 7.10k, False: 8.68k]
  ------------------
  539|  7.10k|                        reverseMappingIndices[index] = static_cast<unsigned int>(vertexRemappingTable->size());
  540|  7.10k|                        vertexRemappingTable->push_back(index);
  541|  7.10k|                    }
  542|  15.7k|                    indexBuffer[i] = reverseMappingIndices[index];
  543|  15.7k|                }
  544|  1.03k|            }
  545|       |
  546|  1.71k|            aiMesh *aim = new aiMesh();
  547|  1.71k|            meshes.push_back(std::unique_ptr<aiMesh>(aim));
  548|       |
  549|  1.71k|            aim->mName = mesh.name.empty() ? mesh.id : mesh.name;
  ------------------
  |  Branch (549:26): [True: 409, False: 1.30k]
  ------------------
  550|       |
  551|  1.71k|            if (mesh.primitives.size() > 1) {
  ------------------
  |  Branch (551:17): [True: 18, False: 1.69k]
  ------------------
  552|     18|                ai_uint32 &len = aim->mName.length;
  553|     18|                aim->mName.data[len] = '-';
  554|     18|                len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(AI_MAXLEN - len - 1), p);
  555|     18|            }
  556|       |
  557|  1.71k|            switch (prim.mode) {
  ------------------
  |  Branch (557:21): [True: 1.68k, False: 27]
  ------------------
  558|     66|            case PrimitiveMode_POINTS:
  ------------------
  |  Branch (558:13): [True: 66, False: 1.64k]
  ------------------
  559|     66|                aim->mPrimitiveTypes |= aiPrimitiveType_POINT;
  560|     66|                break;
  561|       |
  562|    113|            case PrimitiveMode_LINES:
  ------------------
  |  Branch (562:13): [True: 113, False: 1.60k]
  ------------------
  563|    258|            case PrimitiveMode_LINE_LOOP:
  ------------------
  |  Branch (563:13): [True: 145, False: 1.56k]
  ------------------
  564|    351|            case PrimitiveMode_LINE_STRIP:
  ------------------
  |  Branch (564:13): [True: 93, False: 1.62k]
  ------------------
  565|    351|                aim->mPrimitiveTypes |= aiPrimitiveType_LINE;
  566|    351|                break;
  567|       |
  568|    459|            case PrimitiveMode_TRIANGLES:
  ------------------
  |  Branch (568:13): [True: 459, False: 1.25k]
  ------------------
  569|  1.02k|            case PrimitiveMode_TRIANGLE_STRIP:
  ------------------
  |  Branch (569:13): [True: 561, False: 1.15k]
  ------------------
  570|  1.27k|            case PrimitiveMode_TRIANGLE_FAN:
  ------------------
  |  Branch (570:13): [True: 250, False: 1.46k]
  ------------------
  571|  1.27k|                aim->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
  572|  1.27k|                break;
  573|  1.71k|            }
  574|       |
  575|  1.70k|            if (!attr.position.empty() && attr.position[0]) {
  ------------------
  |  Branch (575:17): [True: 1.58k, False: 116]
  |  Branch (575:43): [True: 1.58k, False: 0]
  ------------------
  576|  1.58k|                aim->mNumVertices = static_cast<unsigned int>(attr.position[0]->ExtractData(aim->mVertices, vertexRemappingTable));
  577|  1.58k|            }
  578|       |
  579|  1.70k|            if (!attr.normal.empty() && attr.normal[0]) {
  ------------------
  |  Branch (579:17): [True: 1.19k, False: 515]
  |  Branch (579:41): [True: 1.19k, False: 0]
  ------------------
  580|  1.19k|                    if (attr.normal[0]->count != numAllVertices) {
  ------------------
  |  Branch (580:25): [True: 239, False: 951]
  ------------------
  581|    239|                    DefaultLogger::get()->warn("Normal count in mesh \"", mesh.name, "\" does not match the vertex count, normals ignored.");
  582|    951|                } else {
  583|    951|                    attr.normal[0]->ExtractData(aim->mNormals, vertexRemappingTable);
  584|       |
  585|       |                    // only extract tangents if normals are present
  586|    951|                    if (!attr.tangent.empty() && attr.tangent[0]) {
  ------------------
  |  Branch (586:25): [True: 44, False: 907]
  |  Branch (586:50): [True: 44, False: 0]
  ------------------
  587|     44|                        if (attr.tangent[0]->count != numAllVertices) {
  ------------------
  |  Branch (587:29): [True: 4, False: 40]
  ------------------
  588|      4|                            DefaultLogger::get()->warn("Tangent count in mesh \"", mesh.name, "\" does not match the vertex count, tangents ignored.");
  589|     40|                        } else {
  590|       |                            // generate bitangents from normals and tangents according to spec
  591|     40|                            Tangent *tangents = nullptr;
  592|       |
  593|     40|                            attr.tangent[0]->ExtractData(tangents, vertexRemappingTable);
  594|       |
  595|     40|                            aim->mTangents = new aiVector3D[aim->mNumVertices];
  596|     40|                            aim->mBitangents = new aiVector3D[aim->mNumVertices];
  597|       |
  598|    489|                            for (unsigned int i = 0; i < aim->mNumVertices; ++i) {
  ------------------
  |  Branch (598:54): [True: 449, False: 40]
  ------------------
  599|    449|                                aim->mTangents[i] = tangents[i].xyz;
  600|    449|                                aim->mBitangents[i] = (aim->mNormals[i] ^ tangents[i].xyz) * tangents[i].w;
  601|    449|                            }
  602|       |
  603|     40|                            delete[] tangents;
  604|     40|                        }
  605|     44|                    }
  606|    951|                }
  607|  1.19k|            }
  608|       |
  609|  2.02k|            for (size_t c = 0; c < attr.color.size() && c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c) {
  ------------------
  |  Branch (609:32): [True: 316, False: 1.70k]
  |  Branch (609:57): [True: 316, False: 0]
  ------------------
  610|    316|                if (attr.color[c]->count != numAllVertices) {
  ------------------
  |  Branch (610:21): [True: 34, False: 282]
  ------------------
  611|     34|                    DefaultLogger::get()->warn("Color stream size in mesh \"", mesh.name,
  612|     34|                            "\" does not match the vertex count");
  613|     34|                    continue;
  614|     34|                }
  615|       |
  616|    282|                auto componentType = attr.color[c]->componentType;
  617|    282|                if (componentType == glTF2::ComponentType_FLOAT) {
  ------------------
  |  Branch (617:21): [True: 254, False: 28]
  ------------------
  618|    254|                    attr.color[c]->ExtractData(aim->mColors[c], vertexRemappingTable);
  619|    254|                } else {
  620|     28|                    if (componentType == glTF2::ComponentType_UNSIGNED_BYTE) {
  ------------------
  |  Branch (620:25): [True: 7, False: 21]
  ------------------
  621|      7|                        aim->mColors[c] = GetVertexColorsForType<unsigned char>(attr.color[c], vertexRemappingTable);
  622|     21|                    } else if (componentType == glTF2::ComponentType_UNSIGNED_SHORT) {
  ------------------
  |  Branch (622:32): [True: 8, False: 13]
  ------------------
  623|      8|                        aim->mColors[c] = GetVertexColorsForType<unsigned short>(attr.color[c], vertexRemappingTable);
  624|      8|                    }
  625|     28|                }
  626|    282|            }
  627|  2.16k|            for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
  ------------------
  |  Branch (627:33): [True: 458, False: 1.70k]
  |  Branch (627:62): [True: 458, False: 0]
  ------------------
  628|    458|                if (!attr.texcoord[tc]) {
  ------------------
  |  Branch (628:21): [True: 0, False: 458]
  ------------------
  629|      0|                    DefaultLogger::get()->warn("Texture coordinate accessor not found or non-contiguous texture coordinate sets.");
  630|      0|                    continue;
  631|      0|                }
  632|       |
  633|    458|                if (attr.texcoord[tc]->count != numAllVertices) {
  ------------------
  |  Branch (633:21): [True: 28, False: 430]
  ------------------
  634|     28|                    DefaultLogger::get()->warn("Texcoord stream size in mesh \"", mesh.name,
  635|     28|                            "\" does not match the vertex count");
  636|     28|                    continue;
  637|     28|                }
  638|       |
  639|    430|                attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc], vertexRemappingTable);
  640|    430|                aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();
  641|       |
  642|    430|                aiVector3D *values = aim->mTextureCoords[tc];
  643|  3.85k|                for (unsigned int i = 0; i < aim->mNumVertices; ++i) {
  ------------------
  |  Branch (643:42): [True: 3.42k, False: 430]
  ------------------
  644|  3.42k|                    values[i].y = 1 - values[i].y; // Flip Y coords
  645|  3.42k|                }
  646|    430|            }
  647|       |
  648|  1.70k|            std::vector<Mesh::Primitive::Target> &targets = prim.targets;
  649|  1.70k|            if (!targets.empty()) {
  ------------------
  |  Branch (649:17): [True: 0, False: 1.70k]
  ------------------
  650|      0|                aim->mNumAnimMeshes = (unsigned int)targets.size();
  651|      0|                aim->mAnimMeshes = new aiAnimMesh *[aim->mNumAnimMeshes];
  652|      0|                std::fill(aim->mAnimMeshes, aim->mAnimMeshes + aim->mNumAnimMeshes, nullptr);
  653|      0|                for (size_t i = 0; i < targets.size(); i++) {
  ------------------
  |  Branch (653:36): [True: 0, False: 0]
  ------------------
  654|      0|                    bool needPositions = targets[i].position.size() > 0;
  655|      0|                    bool needNormals = (targets[i].normal.size() > 0) && aim->HasNormals();
  ------------------
  |  Branch (655:40): [True: 0, False: 0]
  |  Branch (655:74): [True: 0, False: 0]
  ------------------
  656|      0|                    bool needTangents = (targets[i].tangent.size() > 0) && aim->HasTangentsAndBitangents();
  ------------------
  |  Branch (656:41): [True: 0, False: 0]
  |  Branch (656:76): [True: 0, False: 0]
  ------------------
  657|       |                    // GLTF morph does not support colors and texCoords
  658|      0|                    aim->mAnimMeshes[i] = aiCreateAnimMesh(aim,
  659|      0|                            needPositions, needNormals, needTangents, false, false);
  660|      0|                    aiAnimMesh &aiAnimMesh = *(aim->mAnimMeshes[i]);
  661|      0|                    Mesh::Primitive::Target &target = targets[i];
  662|       |
  663|      0|                    if (needPositions) {
  ------------------
  |  Branch (663:25): [True: 0, False: 0]
  ------------------
  664|      0|                        if (target.position[0]->count != numAllVertices) {
  ------------------
  |  Branch (664:29): [True: 0, False: 0]
  ------------------
  665|      0|                            ASSIMP_LOG_WARN("Positions of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count");
  666|      0|                        } else {
  667|      0|                            aiVector3D *positionDiff = nullptr;
  668|      0|                            target.position[0]->ExtractData(positionDiff, vertexRemappingTable);
  669|      0|                            for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
  ------------------
  |  Branch (669:61): [True: 0, False: 0]
  ------------------
  670|      0|                                aiAnimMesh.mVertices[vertexId] += positionDiff[vertexId];
  671|      0|                            }
  672|      0|                            delete[] positionDiff;
  673|      0|                        }
  674|      0|                    }
  675|      0|                    if (needNormals) {
  ------------------
  |  Branch (675:25): [True: 0, False: 0]
  ------------------
  676|      0|                        if (target.normal[0]->count != numAllVertices) {
  ------------------
  |  Branch (676:29): [True: 0, False: 0]
  ------------------
  677|      0|                            ASSIMP_LOG_WARN("Normals of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count");
  678|      0|                        } else {
  679|      0|                            aiVector3D *normalDiff = nullptr;
  680|      0|                            target.normal[0]->ExtractData(normalDiff, vertexRemappingTable);
  681|      0|                            for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
  ------------------
  |  Branch (681:61): [True: 0, False: 0]
  ------------------
  682|      0|                                aiAnimMesh.mNormals[vertexId] += normalDiff[vertexId];
  683|      0|                            }
  684|      0|                            delete[] normalDiff;
  685|      0|                        }
  686|      0|                    }
  687|      0|                    if (needTangents) {
  ------------------
  |  Branch (687:25): [True: 0, False: 0]
  ------------------
  688|      0|                        if (!aiAnimMesh.HasNormals()) {
  ------------------
  |  Branch (688:29): [True: 0, False: 0]
  ------------------
  689|       |                            // prevent nullptr access to aiAnimMesh.mNormals below when no normals are available
  690|      0|                            ASSIMP_LOG_WARN("Bitangents of target ", i, " in mesh \"", mesh.name, "\" can't be computed, because mesh has no normals.");
  691|      0|                        } else if (target.tangent[0]->count != numAllVertices) {
  ------------------
  |  Branch (691:36): [True: 0, False: 0]
  ------------------
  692|      0|                            ASSIMP_LOG_WARN("Tangents of target ", i, " in mesh \"", mesh.name, "\" does not match the vertex count");
  693|      0|                        } else {
  694|      0|                            Tangent *tangent = nullptr;
  695|      0|                            attr.tangent[0]->ExtractData(tangent, vertexRemappingTable);
  696|       |
  697|      0|                            aiVector3D *tangentDiff = nullptr;
  698|      0|                            target.tangent[0]->ExtractData(tangentDiff, vertexRemappingTable);
  699|       |
  700|      0|                            for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; ++vertexId) {
  ------------------
  |  Branch (700:61): [True: 0, False: 0]
  ------------------
  701|      0|                                tangent[vertexId].xyz += tangentDiff[vertexId];
  702|      0|                                aiAnimMesh.mTangents[vertexId] = tangent[vertexId].xyz;
  703|      0|                                aiAnimMesh.mBitangents[vertexId] = (aiAnimMesh.mNormals[vertexId] ^ tangent[vertexId].xyz) * tangent[vertexId].w;
  704|      0|                            }
  705|      0|                            delete[] tangent;
  706|      0|                            delete[] tangentDiff;
  707|      0|                        }
  708|      0|                    }
  709|      0|                    if (mesh.weights.size() > i) {
  ------------------
  |  Branch (709:25): [True: 0, False: 0]
  ------------------
  710|      0|                        aiAnimMesh.mWeight = mesh.weights[i];
  711|      0|                    }
  712|      0|                    if (mesh.targetNames.size() > i) {
  ------------------
  |  Branch (712:25): [True: 0, False: 0]
  ------------------
  713|      0|                        aiAnimMesh.mName = mesh.targetNames[i];
  714|      0|                    }
  715|      0|                }
  716|      0|            }
  717|       |
  718|  1.70k|            aiFace *faces = nullptr;
  719|  1.70k|            aiFace *facePtr = nullptr;
  720|  1.70k|            size_t nFaces = 0;
  721|       |
  722|  1.70k|            if (useIndexBuffer) {
  ------------------
  |  Branch (722:17): [True: 1.01k, False: 695]
  ------------------
  723|  1.01k|                size_t count = indexBuffer.size();
  724|       |
  725|  1.01k|                switch (prim.mode) {
  ------------------
  |  Branch (725:25): [True: 1.00k, False: 4]
  ------------------
  726|     41|                case PrimitiveMode_POINTS: {
  ------------------
  |  Branch (726:17): [True: 41, False: 969]
  ------------------
  727|     41|                    nFaces = count;
  728|     41|                    facePtr = faces = new aiFace[nFaces];
  729|  1.20k|                    for (unsigned int i = 0; i < count; ++i) {
  ------------------
  |  Branch (729:46): [True: 1.16k, False: 41]
  ------------------
  730|  1.16k|                        SetFaceAndAdvance1(facePtr, aim->mNumVertices, indexBuffer[i]);
  731|  1.16k|                    }
  732|     41|                    break;
  733|      0|                }
  734|       |
  735|     88|                case PrimitiveMode_LINES: {
  ------------------
  |  Branch (735:17): [True: 88, False: 922]
  ------------------
  736|     88|                    nFaces = count / 2;
  737|     88|                    if (nFaces * 2 != count) {
  ------------------
  |  Branch (737:25): [True: 9, False: 79]
  ------------------
  738|      9|                        ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped.");
  739|      9|                        count = nFaces * 2;
  740|      9|                    }
  741|     88|                    facePtr = faces = new aiFace[nFaces];
  742|  1.58k|                    for (unsigned int i = 0; i < count; i += 2) {
  ------------------
  |  Branch (742:46): [True: 1.50k, False: 88]
  ------------------
  743|  1.50k|                        SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[i], indexBuffer[i + 1]);
  744|  1.50k|                    }
  745|     88|                    break;
  746|      0|                }
  747|       |
  748|     70|                case PrimitiveMode_LINE_LOOP:
  ------------------
  |  Branch (748:17): [True: 70, False: 940]
  ------------------
  749|    155|                case PrimitiveMode_LINE_STRIP: {
  ------------------
  |  Branch (749:17): [True: 85, False: 925]
  ------------------
  750|    155|                    nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
  ------------------
  |  Branch (750:39): [True: 85, False: 70]
  ------------------
  751|    155|                    facePtr = faces = new aiFace[nFaces];
  752|    155|                    SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[0], indexBuffer[1]);
  753|  3.91k|                    for (unsigned int i = 2; i < count; ++i) {
  ------------------
  |  Branch (753:46): [True: 3.76k, False: 155]
  ------------------
  754|  3.76k|                        SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[i - 1], indexBuffer[i]);
  755|  3.76k|                    }
  756|    155|                    if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
  ------------------
  |  Branch (756:25): [True: 70, False: 85]
  ------------------
  757|     70|                        SetFaceAndAdvance2(facePtr, aim->mNumVertices, indexBuffer[static_cast<int>(count) - 1], faces[0].mIndices[0]);
  758|     70|                    }
  759|    155|                    break;
  760|     70|                }
  761|       |
  762|    249|                case PrimitiveMode_TRIANGLES: {
  ------------------
  |  Branch (762:17): [True: 249, False: 761]
  ------------------
  763|    249|                    nFaces = count / 3;
  764|    249|                    if (nFaces * 3 != count) {
  ------------------
  |  Branch (764:25): [True: 13, False: 236]
  ------------------
  765|     13|                        ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped.");
  766|     13|                        count = nFaces * 3;
  767|     13|                    }
  768|       |                    // copycd:: than > 0
  769|    249|                    if (nFaces > 0) {
  ------------------
  |  Branch (769:25): [True: 247, False: 2]
  ------------------
  770|    247|                        facePtr = faces = new aiFace[nFaces];
  771|  2.31k|                        for (unsigned int i = 0; i < count; i += 3) {
  ------------------
  |  Branch (771:50): [True: 2.06k, False: 247]
  ------------------
  772|  2.06k|                            SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[i], indexBuffer[i + 1], indexBuffer[i + 2]);
  773|  2.06k|                        }
  774|    247|                    }
  775|    249|                    break;
  776|     70|                }
  777|    305|                case PrimitiveMode_TRIANGLE_STRIP: {
  ------------------
  |  Branch (777:17): [True: 305, False: 705]
  ------------------
  778|    305|                    nFaces = count - 2;
  779|    305|                    facePtr = faces = new aiFace[nFaces];
  780|  9.04k|                    for (unsigned int i = 0; i < nFaces; ++i) {
  ------------------
  |  Branch (780:46): [True: 8.73k, False: 305]
  ------------------
  781|       |                        // The ordering is to ensure that the triangles are all drawn with the same orientation
  782|  8.73k|                        if ((i + 1) % 2 == 0) {
  ------------------
  |  Branch (782:29): [True: 4.35k, False: 4.38k]
  ------------------
  783|       |                            // For even n, vertices n + 1, n, and n + 2 define triangle n
  784|  4.35k|                            SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[i + 1], indexBuffer[i], indexBuffer[i + 2]);
  785|  4.38k|                        } else {
  786|       |                            // For odd n, vertices n, n+1, and n+2 define triangle n
  787|  4.38k|                            SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[i], indexBuffer[i + 1], indexBuffer[i + 2]);
  788|  4.38k|                        }
  789|  8.73k|                    }
  790|    305|                    break;
  791|     70|                }
  792|    168|                case PrimitiveMode_TRIANGLE_FAN:
  ------------------
  |  Branch (792:17): [True: 168, False: 842]
  ------------------
  793|    168|                    nFaces = count - 2;
  794|    168|                    facePtr = faces = new aiFace[nFaces];
  795|    168|                    SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[0], indexBuffer[1], indexBuffer[2]);
  796|  5.22k|                    for (unsigned int i = 1; i < nFaces; ++i) {
  ------------------
  |  Branch (796:46): [True: 5.05k, False: 168]
  ------------------
  797|  5.05k|                        SetFaceAndAdvance3(facePtr, aim->mNumVertices, indexBuffer[0], indexBuffer[i + 1], indexBuffer[i + 2]);
  798|  5.05k|                    }
  799|    168|                    break;
  800|  1.01k|                }
  801|  1.01k|            } else { // no indices provided so directly generate from counts
  802|       |
  803|       |                // use the already determined count as it includes checks
  804|    695|                unsigned int count = aim->mNumVertices;
  805|       |
  806|    695|                switch (prim.mode) {
  ------------------
  |  Branch (806:25): [True: 658, False: 37]
  ------------------
  807|     24|                case PrimitiveMode_POINTS: {
  ------------------
  |  Branch (807:17): [True: 24, False: 671]
  ------------------
  808|     24|                    nFaces = count;
  809|     24|                    facePtr = faces = new aiFace[nFaces];
  810|    624|                    for (unsigned int i = 0; i < count; ++i) {
  ------------------
  |  Branch (810:46): [True: 600, False: 24]
  ------------------
  811|    600|                        SetFaceAndAdvance1(facePtr, aim->mNumVertices, i);
  812|    600|                    }
  813|     24|                    break;
  814|      0|                }
  815|       |
  816|     24|                case PrimitiveMode_LINES: {
  ------------------
  |  Branch (816:17): [True: 24, False: 671]
  ------------------
  817|     24|                    nFaces = count / 2;
  818|     24|                    if (nFaces * 2 != count) {
  ------------------
  |  Branch (818:25): [True: 1, False: 23]
  ------------------
  819|      1|                        ASSIMP_LOG_WARN("The number of vertices was not compatible with the LINES mode. Some vertices were dropped.");
  820|      1|                        count = (unsigned int)nFaces * 2;
  821|      1|                    }
  822|     24|                    facePtr = faces = new aiFace[nFaces];
  823|    515|                    for (unsigned int i = 0; i < count; i += 2) {
  ------------------
  |  Branch (823:46): [True: 491, False: 24]
  ------------------
  824|    491|                        SetFaceAndAdvance2(facePtr, aim->mNumVertices, i, i + 1);
  825|    491|                    }
  826|     24|                    break;
  827|      0|                }
  828|       |
  829|     75|                case PrimitiveMode_LINE_LOOP:
  ------------------
  |  Branch (829:17): [True: 75, False: 620]
  ------------------
  830|     83|                case PrimitiveMode_LINE_STRIP: {
  ------------------
  |  Branch (830:17): [True: 8, False: 687]
  ------------------
  831|     83|                    nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
  ------------------
  |  Branch (831:39): [True: 8, False: 75]
  ------------------
  832|     83|                    facePtr = faces = new aiFace[nFaces];
  833|     83|                    SetFaceAndAdvance2(facePtr, aim->mNumVertices, 0, 1);
  834|  2.94k|                    for (unsigned int i = 2; i < count; ++i) {
  ------------------
  |  Branch (834:46): [True: 2.85k, False: 83]
  ------------------
  835|  2.85k|                        SetFaceAndAdvance2(facePtr, aim->mNumVertices, i - 1, i);
  836|  2.85k|                    }
  837|     83|                    if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
  ------------------
  |  Branch (837:25): [True: 75, False: 8]
  ------------------
  838|     75|                        SetFaceAndAdvance2(facePtr, aim->mNumVertices, count - 1, 0);
  839|     75|                    }
  840|     83|                    break;
  841|     75|                }
  842|       |
  843|    190|                case PrimitiveMode_TRIANGLES: {
  ------------------
  |  Branch (843:17): [True: 190, False: 505]
  ------------------
  844|    190|                    nFaces = count / 3;
  845|    190|                    if (nFaces * 3 != count) {
  ------------------
  |  Branch (845:25): [True: 50, False: 140]
  ------------------
  846|     50|                        ASSIMP_LOG_WARN("The number of vertices was not compatible with the TRIANGLES mode. Some vertices were dropped.");
  847|     50|                        count = (unsigned int)nFaces * 3;
  848|     50|                    }
  849|    190|                    facePtr = faces = new aiFace[nFaces];
  850|  1.76k|                    for (unsigned int i = 0; i < count; i += 3) {
  ------------------
  |  Branch (850:46): [True: 1.57k, False: 190]
  ------------------
  851|  1.57k|                        SetFaceAndAdvance3(facePtr, aim->mNumVertices, i, i + 1, i + 2);
  852|  1.57k|                    }
  853|    190|                    break;
  854|     75|                }
  855|    255|                case PrimitiveMode_TRIANGLE_STRIP: {
  ------------------
  |  Branch (855:17): [True: 255, False: 440]
  ------------------
  856|    255|                    nFaces = count - 2;
  857|    255|                    facePtr = faces = new aiFace[nFaces];
  858|  17.1k|                    for (unsigned int i = 0; i < nFaces; ++i) {
  ------------------
  |  Branch (858:46): [True: 16.8k, False: 255]
  ------------------
  859|       |                        // The ordering is to ensure that the triangles are all drawn with the same orientation
  860|  16.8k|                        if ((i + 1) % 2 == 0) {
  ------------------
  |  Branch (860:29): [True: 8.42k, False: 8.43k]
  ------------------
  861|       |                            // For even n, vertices n + 1, n, and n + 2 define triangle n
  862|  8.42k|                            SetFaceAndAdvance3(facePtr, aim->mNumVertices, i + 1, i, i + 2);
  863|  8.43k|                        } else {
  864|       |                            // For odd n, vertices n, n+1, and n+2 define triangle n
  865|  8.43k|                            SetFaceAndAdvance3(facePtr, aim->mNumVertices, i, i + 1, i + 2);
  866|  8.43k|                        }
  867|  16.8k|                    }
  868|    255|                    break;
  869|     75|                }
  870|     82|                case PrimitiveMode_TRIANGLE_FAN:
  ------------------
  |  Branch (870:17): [True: 82, False: 613]
  ------------------
  871|     82|                    nFaces = count - 2;
  872|     82|                    facePtr = faces = new aiFace[nFaces];
  873|     82|                    SetFaceAndAdvance3(facePtr, aim->mNumVertices, 0, 1, 2);
  874|  2.93k|                    for (unsigned int i = 1; i < nFaces; ++i) {
  ------------------
  |  Branch (874:46): [True: 2.84k, False: 82]
  ------------------
  875|  2.84k|                        SetFaceAndAdvance3(facePtr, aim->mNumVertices, 0, i + 1, i + 2);
  876|  2.84k|                    }
  877|     82|                    break;
  878|    695|                }
  879|    695|            }
  880|       |
  881|  1.68k|            if (faces) {
  ------------------
  |  Branch (881:17): [True: 1.66k, False: 20]
  ------------------
  882|  1.66k|                aim->mFaces = faces;
  883|  1.66k|                const unsigned int actualNumFaces = static_cast<unsigned int>(facePtr - faces);
  884|  1.66k|                if (actualNumFaces < nFaces) {
  ------------------
  |  Branch (884:21): [True: 861, False: 801]
  ------------------
  885|    861|                    ASSIMP_LOG_WARN("Some faces had out-of-range indices. Those faces were dropped.");
  886|    861|                }
  887|  1.66k|                if (actualNumFaces == 0) {
  ------------------
  |  Branch (887:21): [True: 253, False: 1.40k]
  ------------------
  888|    253|                    throw DeadlyImportError("Mesh \"", aim->mName.C_Str(), "\" has no faces");
  889|    253|                }
  890|  1.40k|                aim->mNumFaces = actualNumFaces;
  891|  1.40k|                ai_assert(CheckValidFacesIndices(faces, actualNumFaces, aim->mNumVertices));
  892|  1.40k|            }
  893|       |
  894|  1.42k|            if (prim.material) {
  ------------------
  |  Branch (894:17): [True: 1.15k, False: 276]
  ------------------
  895|  1.15k|                aim->mMaterialIndex = prim.material.GetIndex();
  896|  1.15k|            } else {
  897|    276|                aim->mMaterialIndex = mScene->mNumMaterials - 1;
  898|    276|            }
  899|  1.42k|        }
  900|  1.75k|    }
  901|       |
  902|  1.70k|    CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes);
  903|  1.70k|}
_ZN6Assimp13glTF2Importer13ImportCamerasERN5glTF25AssetE:
  905|  1.70k|void glTF2Importer::ImportCameras(glTF2::Asset &r) {
  906|  1.70k|    if (!r.cameras.Size()) {
  ------------------
  |  Branch (906:9): [True: 1.70k, False: 0]
  ------------------
  907|  1.70k|        return;
  908|  1.70k|    }
  909|       |
  910|      0|    const unsigned int numCameras = r.cameras.Size();
  911|      0|    ASSIMP_LOG_DEBUG("Importing ", numCameras, " cameras");
  912|      0|    mScene->mNumCameras = numCameras;
  913|      0|    mScene->mCameras = new aiCamera *[numCameras];
  914|      0|    std::fill(mScene->mCameras, mScene->mCameras + numCameras, nullptr);
  915|       |
  916|      0|    for (size_t i = 0; i < numCameras; ++i) {
  ------------------
  |  Branch (916:24): [True: 0, False: 0]
  ------------------
  917|      0|        Camera &cam = r.cameras[i];
  918|       |
  919|      0|        aiCamera *aicam = mScene->mCameras[i] = new aiCamera();
  920|       |
  921|       |        // cameras point in -Z by default, rest is specified in node transform
  922|      0|        aicam->mLookAt = aiVector3D(0.f, 0.f, -1.f);
  923|       |
  924|      0|        if (cam.type == Camera::Perspective) {
  ------------------
  |  Branch (924:13): [True: 0, False: 0]
  ------------------
  925|      0|            aicam->mAspect = cam.cameraProperties.perspective.aspectRatio;
  926|      0|            aicam->mHorizontalFOV = 2.0f * std::atan(std::tan(cam.cameraProperties.perspective.yfov * 0.5f) * ((aicam->mAspect == 0.f) ? 1.f : aicam->mAspect));
  ------------------
  |  Branch (926:112): [True: 0, False: 0]
  ------------------
  927|      0|            aicam->mClipPlaneFar = cam.cameraProperties.perspective.zfar;
  928|      0|            aicam->mClipPlaneNear = cam.cameraProperties.perspective.znear;
  929|      0|        } else {
  930|      0|            aicam->mClipPlaneFar = cam.cameraProperties.ortographic.zfar;
  931|      0|            aicam->mClipPlaneNear = cam.cameraProperties.ortographic.znear;
  932|      0|            aicam->mHorizontalFOV = 0.0;
  933|      0|            aicam->mOrthographicWidth = cam.cameraProperties.ortographic.xmag;
  934|      0|            aicam->mAspect = 1.0f;
  935|      0|            if (0.f != cam.cameraProperties.ortographic.ymag) {
  ------------------
  |  Branch (935:17): [True: 0, False: 0]
  ------------------
  936|      0|                aicam->mAspect = cam.cameraProperties.ortographic.xmag / cam.cameraProperties.ortographic.ymag;
  937|      0|            }
  938|      0|        }
  939|      0|    }
  940|      0|}
_ZN6Assimp13glTF2Importer12ImportLightsERN5glTF25AssetE:
  942|  1.70k|void glTF2Importer::ImportLights(glTF2::Asset &r) {
  943|  1.70k|    if (!r.lights.Size()) {
  ------------------
  |  Branch (943:9): [True: 1.70k, False: 0]
  ------------------
  944|  1.70k|        return;
  945|  1.70k|    }
  946|       |
  947|      0|    const unsigned int numLights = r.lights.Size();
  948|      0|    ASSIMP_LOG_DEBUG("Importing ", numLights, " lights");
  949|      0|    mScene->mNumLights = numLights;
  950|      0|    mScene->mLights = new aiLight *[numLights];
  951|      0|    std::fill(mScene->mLights, mScene->mLights + numLights, nullptr);
  952|       |
  953|      0|    for (size_t i = 0; i < numLights; ++i) {
  ------------------
  |  Branch (953:24): [True: 0, False: 0]
  ------------------
  954|      0|        Light &light = r.lights[i];
  955|       |
  956|      0|        aiLight *ail = mScene->mLights[i] = new aiLight();
  957|       |
  958|      0|        switch (light.type) {
  ------------------
  |  Branch (958:17): [True: 0, False: 0]
  ------------------
  959|      0|        case Light::Directional:
  ------------------
  |  Branch (959:9): [True: 0, False: 0]
  ------------------
  960|      0|            ail->mType = aiLightSource_DIRECTIONAL;
  961|      0|            break;
  962|      0|        case Light::Point:
  ------------------
  |  Branch (962:9): [True: 0, False: 0]
  ------------------
  963|      0|            ail->mType = aiLightSource_POINT;
  964|      0|            break;
  965|      0|        case Light::Spot:
  ------------------
  |  Branch (965:9): [True: 0, False: 0]
  ------------------
  966|      0|            ail->mType = aiLightSource_SPOT;
  967|      0|            break;
  968|      0|        }
  969|       |
  970|      0|        if (ail->mType != aiLightSource_POINT) {
  ------------------
  |  Branch (970:13): [True: 0, False: 0]
  ------------------
  971|      0|            ail->mDirection = aiVector3D(0.0f, 0.0f, -1.0f);
  972|      0|            ail->mUp = aiVector3D(0.0f, 1.0f, 0.0f);
  973|      0|        }
  974|       |
  975|      0|        vec3 colorWithIntensity = { light.color[0] * light.intensity, light.color[1] * light.intensity, light.color[2] * light.intensity };
  976|      0|        CopyValue(colorWithIntensity, ail->mColorAmbient);
  977|      0|        CopyValue(colorWithIntensity, ail->mColorDiffuse);
  978|      0|        CopyValue(colorWithIntensity, ail->mColorSpecular);
  979|       |
  980|      0|        if (ail->mType == aiLightSource_DIRECTIONAL) {
  ------------------
  |  Branch (980:13): [True: 0, False: 0]
  ------------------
  981|      0|            ail->mAttenuationConstant = 1.0;
  982|      0|            ail->mAttenuationLinear = 0.0;
  983|      0|            ail->mAttenuationQuadratic = 0.0;
  984|      0|        } else {
  985|       |            // in PBR attenuation is calculated using inverse square law which can be expressed
  986|       |            // using assimps equation: 1/(att0 + att1 * d + att2 * d*d) with the following parameters
  987|       |            // this is correct equation for the case when range (see
  988|       |            // https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual)
  989|       |            // is not present. When range is not present it is assumed that it is infinite and so numerator is 1.
  990|       |            // When range is present then numerator might be any value in range [0,1] and then assimps equation
  991|       |            // will not suffice. In this case range is added into metadata in ImportNode function
  992|       |            // and its up to implementation to read it when it wants to
  993|      0|            ail->mAttenuationConstant = 0.0;
  994|      0|            ail->mAttenuationLinear = 0.0;
  995|      0|            ail->mAttenuationQuadratic = 1.0;
  996|      0|        }
  997|       |
  998|      0|        if (ail->mType == aiLightSource_SPOT) {
  ------------------
  |  Branch (998:13): [True: 0, False: 0]
  ------------------
  999|      0|            ail->mAngleInnerCone = light.innerConeAngle;
 1000|      0|            ail->mAngleOuterCone = light.outerConeAngle;
 1001|      0|        }
 1002|      0|    }
 1003|      0|}
_Z15ParseExtensionsP10aiMetadataRKN5glTF215CustomExtensionE:
 1110|  18.9k|void ParseExtensions(aiMetadata *metadata, const CustomExtension &extension) {
 1111|  18.9k|    if (extension.mStringValue.isPresent) {
  ------------------
  |  Branch (1111:9): [True: 4.67k, False: 14.2k]
  ------------------
 1112|  4.67k|        metadata->Add(extension.name, aiString(extension.mStringValue.value));
 1113|  14.2k|    } else if (extension.mDoubleValue.isPresent) {
  ------------------
  |  Branch (1113:16): [True: 3, False: 14.2k]
  ------------------
 1114|      3|        metadata->Add(extension.name, extension.mDoubleValue.value);
 1115|  14.2k|    } else if (extension.mUint64Value.isPresent) {
  ------------------
  |  Branch (1115:16): [True: 9.51k, False: 4.71k]
  ------------------
 1116|  9.51k|        metadata->Add(extension.name, extension.mUint64Value.value);
 1117|  9.51k|    } else if (extension.mInt64Value.isPresent) {
  ------------------
  |  Branch (1117:16): [True: 8, False: 4.70k]
  ------------------
 1118|      8|        metadata->Add(extension.name, static_cast<int32_t>(extension.mInt64Value.value));
 1119|  4.70k|    } else if (extension.mBoolValue.isPresent) {
  ------------------
  |  Branch (1119:16): [True: 4.66k, False: 44]
  ------------------
 1120|  4.66k|        metadata->Add(extension.name, extension.mBoolValue.value);
 1121|  4.66k|    } else if (extension.mValues.isPresent) {
  ------------------
  |  Branch (1121:16): [True: 44, False: 0]
  ------------------
 1122|     44|        aiMetadata val;
 1123|    153|        for (auto const &subExtension : extension.mValues.value) {
  ------------------
  |  Branch (1123:39): [True: 153, False: 44]
  ------------------
 1124|    153|            ParseExtensions(&val, subExtension);
 1125|    153|        }
 1126|     44|        metadata->Add(extension.name, val);
 1127|     44|    }
 1128|  18.9k|}
_Z11ParseExtrasP10aiMetadataRKN5glTF26ExtrasE:
 1130|  4.69k|void ParseExtras(aiMetadata* metadata, const Extras& extras) {
 1131|  18.7k|    for (auto const &value : extras.mValues) {
  ------------------
  |  Branch (1131:28): [True: 18.7k, False: 4.69k]
  ------------------
 1132|  18.7k|        ParseExtensions(metadata, value);
 1133|  18.7k|    }
 1134|  4.69k|}
_ZN6Assimp13glTF2Importer10ImportNodeERN5glTF25AssetERN10glTFCommon3RefINS1_4NodeEEE:
 1136|  8.25k|aiNode *glTF2Importer::ImportNode(glTF2::Asset &r, glTF2::Ref<glTF2::Node> &ptr) {
 1137|  8.25k|    Node &node = *ptr;
 1138|       |
 1139|  8.25k|    aiNode *ainode = new aiNode(GetNodeName(node));
 1140|       |
 1141|  8.25k|    try {
 1142|  8.25k|        if (!node.children.empty()) {
  ------------------
  |  Branch (1142:13): [True: 3.72k, False: 4.52k]
  ------------------
 1143|  3.72k|            ainode->mNumChildren = unsigned(node.children.size());
 1144|  3.72k|            ainode->mChildren = new aiNode *[ainode->mNumChildren];
 1145|  3.72k|            std::fill(ainode->mChildren, ainode->mChildren + ainode->mNumChildren, nullptr);
 1146|       |
 1147|  9.71k|            for (unsigned int i = 0; i < ainode->mNumChildren; ++i) {
  ------------------
  |  Branch (1147:38): [True: 5.98k, False: 3.72k]
  ------------------
 1148|  5.98k|                aiNode *child = ImportNode(r, node.children[i]);
 1149|  5.98k|                child->mParent = ainode;
 1150|  5.98k|                ainode->mChildren[i] = child;
 1151|  5.98k|            }
 1152|  3.72k|        }
 1153|       |
 1154|  8.25k|        if (node.customExtensions || node.extras.HasExtras()) {
  ------------------
  |  Branch (1154:13): [True: 84, False: 8.16k]
  |  Branch (1154:38): [True: 4.69k, False: 3.47k]
  ------------------
 1155|  4.69k|            ainode->mMetaData = new aiMetadata;
 1156|  4.69k|            if (node.customExtensions) {
  ------------------
  |  Branch (1156:17): [True: 0, False: 4.69k]
  ------------------
 1157|      0|                ParseExtensions(ainode->mMetaData, node.customExtensions);
 1158|      0|            }
 1159|  4.69k|            if (node.extras.HasExtras()) {
  ------------------
  |  Branch (1159:17): [True: 4.69k, False: 0]
  ------------------
 1160|  4.69k|                ParseExtras(ainode->mMetaData, node.extras);
 1161|  4.69k|            }
 1162|  4.69k|        }
 1163|       |
 1164|  8.25k|        GetNodeTransform(ainode->mTransformation, node);
 1165|       |
 1166|  8.25k|        if (!node.meshes.empty()) {
  ------------------
  |  Branch (1166:13): [True: 1.56k, False: 6.68k]
  ------------------
 1167|       |            // GLTF files contain at most 1 mesh per node.
 1168|  1.56k|            if (node.meshes.size() > 1) {
  ------------------
  |  Branch (1168:17): [True: 0, False: 1.56k]
  ------------------
 1169|      0|                throw DeadlyImportError("GLTF: Invalid input, found ", node.meshes.size(),
 1170|      0|                        " meshes in ", getContextForErrorMessages(node.id, node.name),
 1171|      0|                        ", but only 1 mesh per node allowed.");
 1172|      0|            }
 1173|  1.56k|            int mesh_idx = node.meshes[0].GetIndex();
 1174|  1.56k|            int count = meshOffsets[mesh_idx + 1] - meshOffsets[mesh_idx];
 1175|       |
 1176|  1.56k|            ainode->mNumMeshes = count;
 1177|  1.56k|            ainode->mMeshes = new unsigned int[count];
 1178|       |
 1179|  1.56k|            if (node.skin) {
  ------------------
  |  Branch (1179:17): [True: 288, False: 1.28k]
  ------------------
 1180|    562|                for (int primitiveNo = 0; primitiveNo < count; ++primitiveNo) {
  ------------------
  |  Branch (1180:43): [True: 274, False: 288]
  ------------------
 1181|    274|                    unsigned int aiMeshIdx = meshOffsets[mesh_idx] + primitiveNo;
 1182|    274|                    aiMesh *mesh = mScene->mMeshes[aiMeshIdx];
 1183|    274|                    unsigned int numBones = static_cast<unsigned int>(node.skin->jointNames.size());
 1184|    274|                    std::vector<unsigned int> *vertexRemappingTablePtr = mVertexRemappingTables[aiMeshIdx].empty() ? nullptr : &mVertexRemappingTables[aiMeshIdx];
  ------------------
  |  Branch (1184:74): [True: 66, False: 208]
  ------------------
 1185|       |
 1186|    274|                    std::vector<std::vector<aiVertexWeight>> weighting(numBones);
 1187|    274|                    BuildVertexWeightMapping(node.meshes[0]->primitives[primitiveNo], weighting, vertexRemappingTablePtr);
 1188|       |
 1189|    274|                    mesh->mNumBones = static_cast<unsigned int>(numBones);
 1190|    274|                    mesh->mBones = new aiBone *[mesh->mNumBones];
 1191|    274|                    std::fill(mesh->mBones, mesh->mBones + mesh->mNumBones, nullptr);
 1192|       |
 1193|       |                    // GLTF and Assimp choose to store bone weights differently.
 1194|       |                    // GLTF has each vertex specify which bones influence the vertex.
 1195|       |                    // Assimp has each bone specify which vertices it has influence over.
 1196|       |                    // To convert this data, we first read over the vertex data and pull
 1197|       |                    // out the bone-to-vertex mapping.  Then, when creating the aiBones,
 1198|       |                    // we copy the bone-to-vertex mapping into the bone.  This is unfortunate
 1199|       |                    // both because it's somewhat slow and because, for many applications,
 1200|       |                    // we then need to reconvert the data back into the vertex-to-bone
 1201|       |                    // mapping which makes things doubly-slow.
 1202|       |
 1203|    274|                    mat4 *pbindMatrices = nullptr;
 1204|    274|                    node.skin->inverseBindMatrices->ExtractData(pbindMatrices, nullptr);
 1205|       |
 1206|  2.46k|                    for (uint32_t i = 0; i < numBones; ++i) {
  ------------------
  |  Branch (1206:42): [True: 2.19k, False: 274]
  ------------------
 1207|  2.19k|                        const std::vector<aiVertexWeight> &weights = weighting[i];
 1208|  2.19k|                        aiBone *bone = new aiBone();
 1209|       |
 1210|  2.19k|                        Ref<Node> joint = node.skin->jointNames[i];
 1211|  2.19k|                        if (!joint->name.empty()) {
  ------------------
  |  Branch (1211:29): [True: 2.19k, False: 0]
  ------------------
 1212|  2.19k|                            bone->mName = joint->name;
 1213|  2.19k|                        } else {
 1214|       |                            // Assimp expects each bone to have a unique name.
 1215|      0|                            static const std::string kDefaultName = "bone_";
 1216|      0|                            char postfix[10] = { 0 };
 1217|      0|                            ASSIMP_itoa10(postfix, i);
 1218|      0|                            bone->mName = (kDefaultName + postfix);
 1219|      0|                        }
 1220|  2.19k|                        GetNodeTransform(bone->mOffsetMatrix, *joint);
 1221|  2.19k|                        CopyValue(pbindMatrices[i], bone->mOffsetMatrix);
 1222|  2.19k|                        bone->mNumWeights = static_cast<uint32_t>(weights.size());
 1223|       |
 1224|  2.19k|                        if (bone->mNumWeights > 0) {
  ------------------
  |  Branch (1224:29): [True: 1.15k, False: 1.04k]
  ------------------
 1225|  1.15k|                            bone->mWeights = new aiVertexWeight[bone->mNumWeights];
 1226|  1.15k|                            memcpy(bone->mWeights, weights.data(), bone->mNumWeights * sizeof(aiVertexWeight));
 1227|  1.15k|                        } else {
 1228|       |                            // Assimp expects all bones to have at least 1 weight.
 1229|  1.04k|                            bone->mWeights = new aiVertexWeight[1];
 1230|  1.04k|                            bone->mNumWeights = 1;
 1231|  1.04k|                            bone->mWeights->mVertexId = 0;
 1232|  1.04k|                            bone->mWeights->mWeight = 0.f;
 1233|  1.04k|                        }
 1234|  2.19k|                        mesh->mBones[i] = bone;
 1235|  2.19k|                    }
 1236|       |
 1237|    274|                    if (pbindMatrices) {
  ------------------
  |  Branch (1237:25): [True: 229, False: 45]
  ------------------
 1238|    229|                        delete[] pbindMatrices;
 1239|    229|                    }
 1240|    274|                }
 1241|    288|            }
 1242|       |
 1243|  1.56k|            int k = 0;
 1244|  3.04k|            for (unsigned int j = meshOffsets[mesh_idx]; j < meshOffsets[mesh_idx + 1]; ++j, ++k) {
  ------------------
  |  Branch (1244:58): [True: 1.47k, False: 1.56k]
  ------------------
 1245|  1.47k|                ainode->mMeshes[k] = j;
 1246|  1.47k|            }
 1247|  1.56k|        }
 1248|       |
 1249|  8.25k|        if (node.camera) {
  ------------------
  |  Branch (1249:13): [True: 0, False: 8.25k]
  ------------------
 1250|      0|            mScene->mCameras[node.camera.GetIndex()]->mName = ainode->mName;
 1251|      0|        }
 1252|       |
 1253|  8.25k|        if (node.light) {
  ------------------
  |  Branch (1253:13): [True: 0, False: 8.25k]
  ------------------
 1254|      0|            mScene->mLights[node.light.GetIndex()]->mName = ainode->mName;
 1255|       |
 1256|       |            // range is optional - see https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual
 1257|       |            // it is added to meta data of parent node, because there is no other place to put it
 1258|      0|            if (node.light->range.isPresent) {
  ------------------
  |  Branch (1258:17): [True: 0, False: 0]
  ------------------
 1259|      0|                if (!ainode->mMetaData) {
  ------------------
  |  Branch (1259:21): [True: 0, False: 0]
  ------------------
 1260|      0|                    ainode->mMetaData = aiMetadata::Alloc(1);
 1261|      0|                    ainode->mMetaData->Set(0, "PBR_LightRange", node.light->range.value);
 1262|      0|                } else {
 1263|      0|                    ainode->mMetaData->Add("PBR_LightRange", node.light->range.value);
 1264|      0|                }
 1265|      0|            }
 1266|      0|        }
 1267|       |
 1268|  8.25k|        return ainode;
 1269|  8.25k|    } catch (...) {
 1270|    129|        delete ainode;
 1271|    129|        throw;
 1272|    129|    }
 1273|  8.25k|}
_ZN6Assimp13glTF2Importer11ImportNodesERN5glTF25AssetE:
 1275|  1.70k|void glTF2Importer::ImportNodes(glTF2::Asset &r) {
 1276|  1.70k|    if (!r.scene) {
  ------------------
  |  Branch (1276:9): [True: 127, False: 1.58k]
  ------------------
 1277|    127|        throw DeadlyImportError("GLTF: No scene");
 1278|    127|    }
 1279|  1.70k|    ASSIMP_LOG_DEBUG("Importing nodes");
 1280|       |
 1281|  1.58k|    std::vector<Ref<Node>> rootNodes = r.scene->nodes;
 1282|       |
 1283|       |    // The root nodes
 1284|  1.58k|    unsigned int numRootNodes = unsigned(rootNodes.size());
 1285|  1.58k|    if (numRootNodes == 1) { // a single root node: use it
  ------------------
  |  Branch (1285:9): [True: 1.43k, False: 147]
  ------------------
 1286|  1.43k|        mScene->mRootNode = ImportNode(r, rootNodes[0]);
 1287|  1.43k|    } else if (numRootNodes > 1) { // more than one root node: create a fake root
  ------------------
  |  Branch (1287:16): [True: 109, False: 38]
  ------------------
 1288|    109|        aiNode *root = mScene->mRootNode = new aiNode("ROOT");
 1289|       |
 1290|    109|        root->mChildren = new aiNode *[numRootNodes];
 1291|    109|        std::fill(root->mChildren, root->mChildren + numRootNodes, nullptr);
 1292|       |
 1293|    941|        for (unsigned int i = 0; i < numRootNodes; ++i) {
  ------------------
  |  Branch (1293:34): [True: 832, False: 109]
  ------------------
 1294|    832|            aiNode *node = ImportNode(r, rootNodes[i]);
 1295|    832|            node->mParent = root;
 1296|    832|            root->mChildren[root->mNumChildren++] = node;
 1297|    832|        }
 1298|    109|    } else {
 1299|     38|        mScene->mRootNode = new aiNode("ROOT");
 1300|     38|    }
 1301|  1.58k|}
_ZN6Assimp13glTF2Importer16ImportAnimationsERN5glTF25AssetE:
 1572|  1.53k|void glTF2Importer::ImportAnimations(glTF2::Asset &r) {
 1573|  1.53k|    if (!r.scene) return;
  ------------------
  |  Branch (1573:9): [True: 0, False: 1.53k]
  ------------------
 1574|       |
 1575|  1.53k|    const unsigned numAnimations = r.animations.Size();
 1576|  1.53k|    ASSIMP_LOG_DEBUG("Importing ", numAnimations, " animations");
 1577|  1.53k|    mScene->mNumAnimations = numAnimations;
 1578|  1.53k|    if (mScene->mNumAnimations == 0) {
  ------------------
  |  Branch (1578:9): [True: 1.53k, False: 0]
  ------------------
 1579|  1.53k|        return;
 1580|  1.53k|    }
 1581|       |
 1582|      0|    mScene->mAnimations = new aiAnimation *[numAnimations];
 1583|      0|    std::fill(mScene->mAnimations, mScene->mAnimations + numAnimations, nullptr);
 1584|       |
 1585|      0|    for (unsigned int i = 0; i < numAnimations; ++i) {
  ------------------
  |  Branch (1585:30): [True: 0, False: 0]
  ------------------
 1586|      0|        aiAnimation *ai_anim = mScene->mAnimations[i] = new aiAnimation();
 1587|       |
 1588|      0|        Animation &anim = r.animations[i];
 1589|       |
 1590|      0|        ai_anim->mName = anim.name;
 1591|      0|        ai_anim->mDuration = 0;
 1592|      0|        ai_anim->mTicksPerSecond = 0;
 1593|       |
 1594|      0|        std::unordered_map<unsigned int, AnimationSamplers> samplers = GatherSamplers(anim);
 1595|       |
 1596|      0|        uint32_t numChannels = 0u;
 1597|      0|        uint32_t numMorphMeshChannels = 0u;
 1598|       |
 1599|      0|        for (auto &iter : samplers) {
  ------------------
  |  Branch (1599:25): [True: 0, False: 0]
  ------------------
 1600|      0|            if ((nullptr != iter.second.rotation) || (nullptr != iter.second.scale) || (nullptr != iter.second.translation)) {
  ------------------
  |  Branch (1600:17): [True: 0, False: 0]
  |  Branch (1600:54): [True: 0, False: 0]
  |  Branch (1600:88): [True: 0, False: 0]
  ------------------
 1601|      0|                ++numChannels;
 1602|      0|            }
 1603|      0|            if (nullptr != iter.second.weight) {
  ------------------
  |  Branch (1603:17): [True: 0, False: 0]
  ------------------
 1604|      0|                ++numMorphMeshChannels;
 1605|      0|            }
 1606|      0|        }
 1607|       |
 1608|      0|        ai_anim->mNumChannels = numChannels;
 1609|      0|        if (ai_anim->mNumChannels > 0) {
  ------------------
  |  Branch (1609:13): [True: 0, False: 0]
  ------------------
 1610|      0|            ai_anim->mChannels = new aiNodeAnim *[ai_anim->mNumChannels];
 1611|      0|            std::fill(ai_anim->mChannels, ai_anim->mChannels + ai_anim->mNumChannels, nullptr);
 1612|      0|            int j = 0;
 1613|      0|            for (auto &iter : samplers) {
  ------------------
  |  Branch (1613:29): [True: 0, False: 0]
  ------------------
 1614|      0|                if ((nullptr != iter.second.rotation) || (nullptr != iter.second.scale) || (nullptr != iter.second.translation)) {
  ------------------
  |  Branch (1614:21): [True: 0, False: 0]
  |  Branch (1614:58): [True: 0, False: 0]
  |  Branch (1614:92): [True: 0, False: 0]
  ------------------
 1615|      0|                    ai_anim->mChannels[j] = CreateNodeAnim(r, r.nodes[iter.first], iter.second);
 1616|      0|                    ++j;
 1617|      0|                }
 1618|      0|            }
 1619|      0|        }
 1620|       |
 1621|      0|        ai_anim->mNumMorphMeshChannels = numMorphMeshChannels;
 1622|      0|        if (ai_anim->mNumMorphMeshChannels > 0) {
  ------------------
  |  Branch (1622:13): [True: 0, False: 0]
  ------------------
 1623|      0|            ai_anim->mMorphMeshChannels = new aiMeshMorphAnim *[ai_anim->mNumMorphMeshChannels];
 1624|      0|            std::fill(ai_anim->mMorphMeshChannels, ai_anim->mMorphMeshChannels + ai_anim->mNumMorphMeshChannels, nullptr);
 1625|      0|            int j = 0;
 1626|      0|            for (auto &iter : samplers) {
  ------------------
  |  Branch (1626:29): [True: 0, False: 0]
  ------------------
 1627|      0|                if (nullptr != iter.second.weight) {
  ------------------
  |  Branch (1627:21): [True: 0, False: 0]
  ------------------
 1628|      0|                    ai_anim->mMorphMeshChannels[j] = CreateMeshMorphAnim(r, r.nodes[iter.first], iter.second);
 1629|      0|                    ++j;
 1630|      0|                }
 1631|      0|            }
 1632|      0|        }
 1633|       |
 1634|       |        // Use the latest key-frame for the duration of the animation
 1635|      0|        double maxDuration = 0;
 1636|      0|        unsigned int maxNumberOfKeys = 0;
 1637|      0|        for (unsigned int j = 0; j < ai_anim->mNumChannels; ++j) {
  ------------------
  |  Branch (1637:34): [True: 0, False: 0]
  ------------------
 1638|      0|            auto chan = ai_anim->mChannels[j];
 1639|      0|            if (chan->mNumPositionKeys) {
  ------------------
  |  Branch (1639:17): [True: 0, False: 0]
  ------------------
 1640|      0|                auto lastPosKey = chan->mPositionKeys[chan->mNumPositionKeys - 1];
 1641|      0|                if (lastPosKey.mTime > maxDuration) {
  ------------------
  |  Branch (1641:21): [True: 0, False: 0]
  ------------------
 1642|      0|                    maxDuration = lastPosKey.mTime;
 1643|      0|                }
 1644|      0|                maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumPositionKeys);
 1645|      0|            }
 1646|      0|            if (chan->mNumRotationKeys) {
  ------------------
  |  Branch (1646:17): [True: 0, False: 0]
  ------------------
 1647|      0|                auto lastRotKey = chan->mRotationKeys[chan->mNumRotationKeys - 1];
 1648|      0|                if (lastRotKey.mTime > maxDuration) {
  ------------------
  |  Branch (1648:21): [True: 0, False: 0]
  ------------------
 1649|      0|                    maxDuration = lastRotKey.mTime;
 1650|      0|                }
 1651|      0|                maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumRotationKeys);
 1652|      0|            }
 1653|      0|            if (chan->mNumScalingKeys) {
  ------------------
  |  Branch (1653:17): [True: 0, False: 0]
  ------------------
 1654|      0|                auto lastScaleKey = chan->mScalingKeys[chan->mNumScalingKeys - 1];
 1655|      0|                if (lastScaleKey.mTime > maxDuration) {
  ------------------
  |  Branch (1655:21): [True: 0, False: 0]
  ------------------
 1656|      0|                    maxDuration = lastScaleKey.mTime;
 1657|      0|                }
 1658|      0|                maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumScalingKeys);
 1659|      0|            }
 1660|      0|        }
 1661|       |
 1662|      0|        for (unsigned int j = 0; j < ai_anim->mNumMorphMeshChannels; ++j) {
  ------------------
  |  Branch (1662:34): [True: 0, False: 0]
  ------------------
 1663|      0|            const auto *const chan = ai_anim->mMorphMeshChannels[j];
 1664|       |
 1665|      0|            if (0u != chan->mNumKeys) {
  ------------------
  |  Branch (1665:17): [True: 0, False: 0]
  ------------------
 1666|      0|                const auto &lastKey = chan->mKeys[chan->mNumKeys - 1u];
 1667|      0|                if (lastKey.mTime > maxDuration) {
  ------------------
  |  Branch (1667:21): [True: 0, False: 0]
  ------------------
 1668|      0|                    maxDuration = lastKey.mTime;
 1669|      0|                }
 1670|      0|                maxNumberOfKeys = std::max(maxNumberOfKeys, chan->mNumKeys);
 1671|      0|            }
 1672|      0|        }
 1673|       |
 1674|      0|        ai_anim->mDuration = maxDuration;
 1675|      0|        ai_anim->mTicksPerSecond = 1000.0;
 1676|      0|    }
 1677|      0|}
_ZN6Assimp13glTF2Importer22ImportEmbeddedTexturesERN5glTF25AssetE:
 1690|  2.00k|void glTF2Importer::ImportEmbeddedTextures(glTF2::Asset &r) {
 1691|  2.00k|    mEmbeddedTexIdxs.resize(r.images.Size(), -1);
 1692|  2.00k|    const unsigned int numEmbeddedTexs = countEmbeddedTextures(r);
 1693|  2.00k|    if (numEmbeddedTexs == 0) {
  ------------------
  |  Branch (1693:9): [True: 1.95k, False: 47]
  ------------------
 1694|  1.95k|        return;
 1695|  1.95k|    }
 1696|       |
 1697|  2.00k|    ASSIMP_LOG_DEBUG("Importing ", numEmbeddedTexs, " embedded textures");
 1698|       |
 1699|     47|    mScene->mTextures = new aiTexture *[numEmbeddedTexs];
 1700|     47|    std::fill(mScene->mTextures, mScene->mTextures + numEmbeddedTexs, nullptr);
 1701|       |
 1702|       |    // Add the embedded textures
 1703|     94|    for (size_t i = 0; i < r.images.Size(); ++i) {
  ------------------
  |  Branch (1703:24): [True: 47, False: 47]
  ------------------
 1704|     47|        Image &img = r.images[i];
 1705|     47|        if (!img.HasData()) {
  ------------------
  |  Branch (1705:13): [True: 0, False: 47]
  ------------------
 1706|      0|            continue;
 1707|      0|        }
 1708|       |
 1709|     47|        int idx = mScene->mNumTextures++;
 1710|     47|        mEmbeddedTexIdxs[i] = idx;
 1711|       |
 1712|     47|        aiTexture *tex = mScene->mTextures[idx] = new aiTexture();
 1713|       |
 1714|     47|        size_t length = img.GetDataLength();
 1715|     47|        void *data = img.StealData();
 1716|       |
 1717|     47|        tex->mFilename = img.name;
 1718|     47|        tex->mWidth = static_cast<unsigned int>(length);
 1719|     47|        tex->mHeight = 0;
 1720|     47|        tex->pcData = reinterpret_cast<aiTexel *>(data);
 1721|       |
 1722|     47|        if (!img.mimeType.empty()) {
  ------------------
  |  Branch (1722:13): [True: 47, False: 0]
  ------------------
 1723|     47|            const char *ext = strchr(img.mimeType.c_str(), '/') + 1;
 1724|     47|            if (ext) {
  ------------------
  |  Branch (1724:17): [True: 47, False: 0]
  ------------------
 1725|     47|                if (strncmp(ext, "jpeg", 4) == 0) {
  ------------------
  |  Branch (1725:21): [True: 0, False: 47]
  ------------------
 1726|      0|                    ext = "jpg";
 1727|     47|                } else if (strcmp(ext, "ktx2") == 0) { // basisu: ktx remains
  ------------------
  |  Branch (1727:28): [True: 0, False: 47]
  ------------------
 1728|      0|                    ext = "kx2";
 1729|     47|                } else if (strcmp(ext, "basis") == 0) { // basisu
  ------------------
  |  Branch (1729:28): [True: 0, False: 47]
  ------------------
 1730|      0|                    ext = "bu";
 1731|      0|                } // webp requires no transformation
 1732|       |
 1733|     47|                size_t len = strlen(ext);
 1734|     47|                if (len > 3) len = 3;
  ------------------
  |  Branch (1734:21): [True: 2, False: 45]
  ------------------
 1735|     47|                tex->achFormatHint[3] = '\0';
 1736|     47|                memcpy(tex->achFormatHint, ext, len);
 1737|     47|            }
 1738|     47|        }
 1739|     47|    }
 1740|     47|}
_ZN6Assimp13glTF2Importer20ImportCommonMetadataERN5glTF25AssetE:
 1742|  1.53k|void glTF2Importer::ImportCommonMetadata(glTF2::Asset &a) {
 1743|  1.53k|    ASSIMP_LOG_DEBUG("Importing metadata");
 1744|  1.53k|    ai_assert(mScene->mMetaData == nullptr);
 1745|  1.53k|    const bool hasVersion = !a.asset.version.empty();
 1746|  1.53k|    const bool hasGenerator = !a.asset.generator.empty();
 1747|  1.53k|    const bool hasCopyright = !a.asset.copyright.empty();
 1748|  1.53k|    const bool hasSceneMetadata = a.scene->customExtensions;
 1749|  1.53k|    const bool hasSceneExtras = a.scene->extras.HasExtras();
 1750|  1.53k|    if (hasVersion || hasGenerator || hasCopyright || hasSceneMetadata || hasSceneExtras) {
  ------------------
  |  Branch (1750:9): [True: 1.53k, False: 0]
  |  Branch (1750:23): [True: 0, False: 0]
  |  Branch (1750:39): [True: 0, False: 0]
  |  Branch (1750:55): [True: 0, False: 0]
  |  Branch (1750:75): [True: 0, False: 0]
  ------------------
 1751|  1.53k|        mScene->mMetaData = new aiMetadata;
 1752|  1.53k|        if (hasVersion) {
  ------------------
  |  Branch (1752:13): [True: 1.53k, False: 0]
  ------------------
 1753|  1.53k|            mScene->mMetaData->Add(AI_METADATA_SOURCE_FORMAT_VERSION, aiString(a.asset.version));
 1754|  1.53k|        }
 1755|  1.53k|        if (hasGenerator) {
  ------------------
  |  Branch (1755:13): [True: 1.12k, False: 406]
  ------------------
 1756|  1.12k|            mScene->mMetaData->Add(AI_METADATA_SOURCE_GENERATOR, aiString(a.asset.generator));
 1757|  1.12k|        }
 1758|  1.53k|        if (hasCopyright) {
  ------------------
  |  Branch (1758:13): [True: 8, False: 1.52k]
  ------------------
 1759|      8|            mScene->mMetaData->Add(AI_METADATA_SOURCE_COPYRIGHT, aiString(a.asset.copyright));
 1760|      8|        }
 1761|  1.53k|        if (hasSceneMetadata) {
  ------------------
  |  Branch (1761:13): [True: 0, False: 1.53k]
  ------------------
 1762|      0|            ParseExtensions(mScene->mMetaData, a.scene->customExtensions);
 1763|      0|        }
 1764|  1.53k|        if (hasSceneExtras) {
  ------------------
  |  Branch (1764:13): [True: 1, False: 1.53k]
  ------------------
 1765|      1|            ParseExtras(mScene->mMetaData, a.scene->extras);
 1766|      1|        }
 1767|  1.53k|    }
 1768|  1.53k|}
_ZN6Assimp13glTF2Importer14InternReadFileERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP7aiScenePNS_8IOSystemE:
 1770|  2.39k|void glTF2Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
 1771|  2.39k|    ASSIMP_LOG_DEBUG("Reading GLTF2 file");
 1772|       |
 1773|       |    // clean all member arrays
 1774|  2.39k|    meshOffsets.clear();
 1775|  2.39k|    mVertexRemappingTables.clear();
 1776|  2.39k|    mEmbeddedTexIdxs.clear();
 1777|       |
 1778|  2.39k|    this->mScene = pScene;
 1779|       |
 1780|       |    // read the asset file
 1781|  2.39k|    glTF2::Asset asset(pIOHandler, static_cast<rapidjson::IRemoteSchemaDocumentProvider *>(mSchemaDocumentProvider));
 1782|  2.39k|    asset.Load(pFile,
 1783|  2.39k|               CheckMagicToken(
 1784|  2.39k|                   pIOHandler, pFile, AI_GLB_MAGIC_NUMBER, 1, 0,
  ------------------
  |  |  147|  2.39k|#define AI_GLB_MAGIC_NUMBER "glTF"
  ------------------
 1785|  2.39k|                   static_cast<unsigned int>(strlen(AI_GLB_MAGIC_NUMBER))));
  ------------------
  |  |  147|  2.39k|#define AI_GLB_MAGIC_NUMBER "glTF"
  ------------------
 1786|  2.39k|    if (asset.scene) {
  ------------------
  |  Branch (1786:9): [True: 1.87k, False: 514]
  ------------------
 1787|  1.87k|        pScene->mName = asset.scene->name;
 1788|  1.87k|    }
 1789|       |
 1790|       |    // Copy the data out
 1791|  2.39k|    ImportEmbeddedTextures(asset);
 1792|  2.39k|    ImportMaterials(asset);
 1793|       |
 1794|  2.39k|    ImportMeshes(asset);
 1795|       |
 1796|  2.39k|    ImportCameras(asset);
 1797|  2.39k|    ImportLights(asset);
 1798|       |
 1799|  2.39k|    ImportNodes(asset);
 1800|       |
 1801|  2.39k|    ImportAnimations(asset);
 1802|       |
 1803|  2.39k|    ImportCommonMetadata(asset);
 1804|       |
 1805|  2.39k|    if (pScene->mNumMeshes == 0) {
  ------------------
  |  Branch (1805:9): [True: 159, False: 2.23k]
  ------------------
 1806|       |        pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
 1807|    159|    }
 1808|  2.39k|}
_ZN6Assimp13glTF2Importer15SetupPropertiesEPKNS_8ImporterE:
 1810|  2.39k|void glTF2Importer::SetupProperties(const Importer *pImp) {
 1811|       |    mSchemaDocumentProvider = static_cast<rapidjson::IRemoteSchemaDocumentProvider *>(pImp->GetPropertyPointer(AI_CONFIG_IMPORT_SCHEMA_DOCUMENT_PROVIDER));
 1812|  2.39k|}
glTF2Importer.cpp:_ZL14ImportMaterialRNSt3__16vectorIiNS_9allocatorIiEEEERN5glTF25AssetERNS5_8MaterialE:
  244|  3.40k|static aiMaterial *ImportMaterial(std::vector<int> &embeddedTexIdxs, Asset &r, Material &mat) {
  245|  3.40k|    aiMaterial *aimat = new aiMaterial();
  246|       |
  247|  3.40k|    try {
  248|  3.40k|        if (!mat.name.empty()) {
  ------------------
  |  Branch (248:13): [True: 1.35k, False: 2.05k]
  ------------------
  249|  1.35k|            aiString str(mat.name);
  250|       |
  251|  1.35k|            aimat->AddProperty(&str, AI_MATKEY_NAME);
  252|  1.35k|        }
  253|       |
  254|       |        // Set Assimp DIFFUSE and BASE COLOR to the pbrMetallicRoughness base color and texture for backwards compatibility
  255|       |        // Technically should not load any pbrMetallicRoughness if extensionsRequired contains KHR_materials_pbrSpecularGlossiness
  256|  3.40k|        SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_COLOR_DIFFUSE);
  257|  3.40k|        SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_BASE_COLOR);
  258|       |
  259|  3.40k|        SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, aiTextureType_DIFFUSE);
  260|  3.40k|        SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, aiTextureType_BASE_COLOR);
  261|       |
  262|       |        // Keep AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE for backwards compatibility
  263|  3.40k|        SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.metallicRoughnessTexture, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE);
  264|  3.40k|        SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.metallicRoughnessTexture, aimat, aiTextureType_METALNESS);
  265|  3.40k|        SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.metallicRoughnessTexture, aimat, aiTextureType_DIFFUSE_ROUGHNESS);
  266|       |
  267|  3.40k|        aimat->AddProperty(&mat.pbrMetallicRoughness.metallicFactor, 1, AI_MATKEY_METALLIC_FACTOR);
  268|  3.40k|        aimat->AddProperty(&mat.pbrMetallicRoughness.roughnessFactor, 1, AI_MATKEY_ROUGHNESS_FACTOR);
  269|       |
  270|  3.40k|        float roughnessAsShininess = 1 - mat.pbrMetallicRoughness.roughnessFactor;
  271|  3.40k|        roughnessAsShininess *= roughnessAsShininess * 1000;
  272|  3.40k|        aimat->AddProperty(&roughnessAsShininess, 1, AI_MATKEY_SHININESS);
  273|       |
  274|  3.40k|        SetMaterialTextureProperty(embeddedTexIdxs, r, mat.normalTexture, aimat, aiTextureType_NORMALS);
  275|  3.40k|        SetMaterialTextureProperty(embeddedTexIdxs, r, mat.occlusionTexture, aimat, aiTextureType_LIGHTMAP);
  276|  3.40k|        SetMaterialTextureProperty(embeddedTexIdxs, r, mat.emissiveTexture, aimat, aiTextureType_EMISSIVE);
  277|  3.40k|        SetMaterialColorProperty(r, mat.emissiveFactor, aimat, AI_MATKEY_COLOR_EMISSIVE);
  278|       |
  279|  3.40k|        aimat->AddProperty(&mat.doubleSided, 1, AI_MATKEY_TWOSIDED);
  280|  3.40k|        aimat->AddProperty(&mat.pbrMetallicRoughness.baseColorFactor[3], 1, AI_MATKEY_OPACITY);
  281|       |
  282|  3.40k|        aiString alphaMode(mat.alphaMode);
  283|  3.40k|        aimat->AddProperty(&alphaMode, AI_MATKEY_GLTF_ALPHAMODE);
  284|  3.40k|        aimat->AddProperty(&mat.alphaCutoff, 1, AI_MATKEY_GLTF_ALPHACUTOFF);
  285|       |
  286|       |        // KHR_materials_specular
  287|  3.40k|        if (mat.materialSpecular.isPresent) {
  ------------------
  |  Branch (287:13): [True: 0, False: 3.40k]
  ------------------
  288|      0|            MaterialSpecular &specular = mat.materialSpecular.value;
  289|       |            // Default values of zero disables Specular
  290|      0|            if (std::memcmp(specular.specularColorFactor, defaultSpecularColorFactor, sizeof(vec3)) != 0 || specular.specularFactor != 0.0f) {
  ------------------
  |  Branch (290:17): [True: 0, False: 0]
  |  Branch (290:109): [True: 0, False: 0]
  ------------------
  291|      0|                SetMaterialColorProperty(r, specular.specularColorFactor, aimat, AI_MATKEY_COLOR_SPECULAR);
  292|      0|                aimat->AddProperty(&specular.specularFactor, 1, AI_MATKEY_SPECULAR_FACTOR);
  293|      0|                SetMaterialTextureProperty(embeddedTexIdxs, r, specular.specularTexture, aimat, aiTextureType_SPECULAR, 0);
  294|      0|                SetMaterialTextureProperty(embeddedTexIdxs, r, specular.specularColorTexture, aimat, aiTextureType_SPECULAR, 1);
  295|      0|            }
  296|      0|        }
  297|       |        // pbrSpecularGlossiness
  298|  3.40k|        else if (mat.pbrSpecularGlossiness.isPresent) {
  ------------------
  |  Branch (298:18): [True: 0, False: 3.40k]
  ------------------
  299|      0|            PbrSpecularGlossiness &pbrSG = mat.pbrSpecularGlossiness.value;
  300|       |
  301|      0|            SetMaterialColorProperty(r, pbrSG.diffuseFactor, aimat, AI_MATKEY_COLOR_DIFFUSE);
  302|      0|            SetMaterialColorProperty(r, pbrSG.specularFactor, aimat, AI_MATKEY_COLOR_SPECULAR);
  303|       |
  304|      0|            float glossinessAsShininess = pbrSG.glossinessFactor * 1000.0f;
  305|      0|            aimat->AddProperty(&glossinessAsShininess, 1, AI_MATKEY_SHININESS);
  306|      0|            aimat->AddProperty(&pbrSG.glossinessFactor, 1, AI_MATKEY_GLOSSINESS_FACTOR);
  307|       |
  308|      0|            SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.diffuseTexture, aimat, aiTextureType_DIFFUSE);
  309|       |
  310|      0|            SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.specularGlossinessTexture, aimat, aiTextureType_SPECULAR);
  311|      0|        }
  312|       |
  313|       |        // glTFv2 is either PBR or Unlit
  314|  3.40k|        aiShadingMode shadingMode = aiShadingMode_PBR_BRDF;
  315|  3.40k|        if (mat.unlit) {
  ------------------
  |  Branch (315:13): [True: 0, False: 3.40k]
  ------------------
  316|      0|            aimat->AddProperty(&mat.unlit, 1, "$mat.gltf.unlit", 0, 0); // TODO: Remove this property, it is kept for backwards compatibility with assimp 5.0.1
  317|      0|            shadingMode = aiShadingMode_Unlit;
  318|      0|        }
  319|       |
  320|  3.40k|        aimat->AddProperty(&shadingMode, 1, AI_MATKEY_SHADING_MODEL);
  321|       |
  322|       |        // KHR_materials_sheen
  323|  3.40k|        if (mat.materialSheen.isPresent) {
  ------------------
  |  Branch (323:13): [True: 0, False: 3.40k]
  ------------------
  324|      0|            MaterialSheen &sheen = mat.materialSheen.value;
  325|       |            // Default value {0,0,0} disables Sheen
  326|      0|            if (std::memcmp(sheen.sheenColorFactor, defaultSheenFactor, sizeof(glTFCommon::vec3)) != 0) {
  ------------------
  |  Branch (326:17): [True: 0, False: 0]
  ------------------
  327|      0|                SetMaterialColorProperty(r, sheen.sheenColorFactor, aimat, AI_MATKEY_SHEEN_COLOR_FACTOR);
  328|      0|                aimat->AddProperty(&sheen.sheenRoughnessFactor, 1, AI_MATKEY_SHEEN_ROUGHNESS_FACTOR);
  329|      0|                SetMaterialTextureProperty(embeddedTexIdxs, r, sheen.sheenColorTexture, aimat, AI_MATKEY_SHEEN_COLOR_TEXTURE);
  330|      0|                SetMaterialTextureProperty(embeddedTexIdxs, r, sheen.sheenRoughnessTexture, aimat, AI_MATKEY_SHEEN_ROUGHNESS_TEXTURE);
  331|      0|            }
  332|      0|        }
  333|       |
  334|       |        // KHR_materials_clearcoat
  335|  3.40k|        if (mat.materialClearcoat.isPresent) {
  ------------------
  |  Branch (335:13): [True: 0, False: 3.40k]
  ------------------
  336|      0|            MaterialClearcoat &clearcoat = mat.materialClearcoat.value;
  337|       |            // Default value 0.0 disables clearcoat
  338|      0|            if (clearcoat.clearcoatFactor != 0.0f) {
  ------------------
  |  Branch (338:17): [True: 0, False: 0]
  ------------------
  339|      0|                aimat->AddProperty(&clearcoat.clearcoatFactor, 1, AI_MATKEY_CLEARCOAT_FACTOR);
  340|      0|                aimat->AddProperty(&clearcoat.clearcoatRoughnessFactor, 1, AI_MATKEY_CLEARCOAT_ROUGHNESS_FACTOR);
  341|      0|                SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatTexture, aimat, AI_MATKEY_CLEARCOAT_TEXTURE);
  342|      0|                SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatRoughnessTexture, aimat, AI_MATKEY_CLEARCOAT_ROUGHNESS_TEXTURE);
  343|      0|                SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatNormalTexture, aimat, AI_MATKEY_CLEARCOAT_NORMAL_TEXTURE);
  344|      0|            }
  345|      0|        }
  346|       |
  347|       |        // KHR_materials_transmission
  348|  3.40k|        if (mat.materialTransmission.isPresent) {
  ------------------
  |  Branch (348:13): [True: 0, False: 3.40k]
  ------------------
  349|      0|            MaterialTransmission &transmission = mat.materialTransmission.value;
  350|       |
  351|      0|            aimat->AddProperty(&transmission.transmissionFactor, 1, AI_MATKEY_TRANSMISSION_FACTOR);
  352|      0|            SetMaterialTextureProperty(embeddedTexIdxs, r, transmission.transmissionTexture, aimat, AI_MATKEY_TRANSMISSION_TEXTURE);
  353|      0|        }
  354|       |
  355|       |        // KHR_materials_volume
  356|  3.40k|        if (mat.materialVolume.isPresent) {
  ------------------
  |  Branch (356:13): [True: 0, False: 3.40k]
  ------------------
  357|      0|            MaterialVolume &volume = mat.materialVolume.value;
  358|       |
  359|      0|            aimat->AddProperty(&volume.thicknessFactor, 1, AI_MATKEY_VOLUME_THICKNESS_FACTOR);
  360|      0|            SetMaterialTextureProperty(embeddedTexIdxs, r, volume.thicknessTexture, aimat, AI_MATKEY_VOLUME_THICKNESS_TEXTURE);
  361|      0|            aimat->AddProperty(&volume.attenuationDistance, 1, AI_MATKEY_VOLUME_ATTENUATION_DISTANCE);
  362|      0|            SetMaterialColorProperty(r, volume.attenuationColor, aimat, AI_MATKEY_VOLUME_ATTENUATION_COLOR);
  363|      0|        }
  364|       |
  365|       |        // KHR_materials_ior
  366|  3.40k|        if (mat.materialIOR.isPresent) {
  ------------------
  |  Branch (366:13): [True: 0, False: 3.40k]
  ------------------
  367|      0|            MaterialIOR &ior = mat.materialIOR.value;
  368|       |
  369|      0|            aimat->AddProperty(&ior.ior, 1, AI_MATKEY_REFRACTI);
  370|      0|        }
  371|       |
  372|       |        // KHR_materials_emissive_strength
  373|  3.40k|        if (mat.materialEmissiveStrength.isPresent) {
  ------------------
  |  Branch (373:13): [True: 0, False: 3.40k]
  ------------------
  374|      0|            const MaterialEmissiveStrength &emissiveStrength = mat.materialEmissiveStrength.value;
  375|       |
  376|      0|            aimat->AddProperty(&emissiveStrength.emissiveStrength, 1, AI_MATKEY_EMISSIVE_INTENSITY);
  377|      0|        }
  378|       |
  379|       |        // KHR_materials_anisotropy
  380|  3.40k|        if (mat.materialAnisotropy.isPresent) {
  ------------------
  |  Branch (380:13): [True: 0, False: 3.40k]
  ------------------
  381|      0|            const MaterialAnisotropy &anisotropy = mat.materialAnisotropy.value;
  382|       |
  383|      0|            aimat->AddProperty(&anisotropy.anisotropyStrength, 1, AI_MATKEY_ANISOTROPY_FACTOR);
  384|      0|            aimat->AddProperty(&anisotropy.anisotropyRotation, 1, AI_MATKEY_ANISOTROPY_ROTATION);
  385|       |
  386|      0|            SetMaterialTextureProperty(embeddedTexIdxs, r, anisotropy.anisotropyTexture, aimat, AI_MATKEY_ANISOTROPY_TEXTURE);
  387|      0|        }
  388|       |
  389|  3.40k|        return aimat;
  390|  3.40k|    } catch (...) {
  391|      0|        delete aimat;
  392|      0|        throw;
  393|      0|    }
  394|  3.40k|}
glTF2Importer.cpp:_ZL24SetMaterialColorPropertyRN5glTF25AssetERA4_fP10aiMaterialPKcjj:
  144|  6.80k|        const char *pKey, unsigned int type, unsigned int idx) {
  145|  6.80k|    aiColor4D col;
  146|  6.80k|    CopyValue(prop, col);
  147|  6.80k|    mat->AddProperty(&col, 1, pKey, type, idx);
  148|  6.80k|}
glTF2Importer.cpp:_ZL26SetMaterialTexturePropertyRNSt3__16vectorIiNS_9allocatorIiEEEERN5glTF25AssetENS5_11TextureInfoEP10aiMaterial13aiTextureTypej:
  159|  27.2k|        unsigned int texSlot = 0) {
  160|  27.2k|    if (prop.texture && prop.texture->source) {
  ------------------
  |  Branch (160:9): [True: 118, False: 27.0k]
  |  Branch (160:25): [True: 96, False: 22]
  ------------------
  161|     96|        aiString uri(prop.texture->source->uri);
  162|       |
  163|     96|        int texIdx = embeddedTexIdxs[prop.texture->source.GetIndex()];
  164|     96|        if (texIdx != -1) { // embedded
  ------------------
  |  Branch (164:13): [True: 94, False: 2]
  ------------------
  165|       |            // setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
  166|     94|            uri.data[0] = '*';
  167|     94|            uri.length = 1 + ASSIMP_itoa10(uri.data + 1, AI_MAXLEN - 1, texIdx);
  168|     94|        }
  169|       |
  170|     96|        mat->AddProperty(&uri, AI_MATKEY_TEXTURE(texType, texSlot));
  171|     96|        const int uvIndex = static_cast<int>(prop.texCoord);
  172|     96|        mat->AddProperty(&uvIndex, 1, AI_MATKEY_UVWSRC(texType, texSlot));
  173|       |
  174|     96|        if (prop.textureTransformSupported) {
  ------------------
  |  Branch (174:13): [True: 0, False: 96]
  ------------------
  175|      0|            aiUVTransform transform;
  176|      0|            transform.mScaling.x = prop.TextureTransformExt_t.scale[0];
  177|      0|            transform.mScaling.y = prop.TextureTransformExt_t.scale[1];
  178|      0|            transform.mRotation = -prop.TextureTransformExt_t.rotation; // must be negated
  179|       |
  180|       |            // A change of coordinates is required to map glTF UV transformations into the space used by
  181|       |            // Assimp. In glTF all UV origins are at 0,1 (top left of texture) in Assimp space. In Assimp
  182|       |            // rotation occurs around the image center (0.5,0.5) where as in glTF rotation is around the
  183|       |            // texture origin. All three can be corrected for solely by a change of the translation since
  184|       |            // the transformations available are shape preserving. Note the importer already flips the V
  185|       |            // coordinate of the actual meshes during import.
  186|      0|            const ai_real rcos(cos(-transform.mRotation));
  187|      0|            const ai_real rsin(sin(-transform.mRotation));
  188|      0|            transform.mTranslation.x = (static_cast<ai_real>(0.5) * transform.mScaling.x) * (-rcos + rsin + 1) + prop.TextureTransformExt_t.offset[0];
  189|      0|            transform.mTranslation.y = ((static_cast<ai_real>(0.5) * transform.mScaling.y) * (rsin + rcos - 1)) + 1 - transform.mScaling.y - prop.TextureTransformExt_t.offset[1];
  190|       |
  191|      0|            mat->AddProperty(&transform, 1, _AI_MATKEY_UVTRANSFORM_BASE, texType, texSlot);
  192|      0|        }
  193|       |
  194|     96|        if (prop.texture->sampler) {
  ------------------
  |  Branch (194:13): [True: 90, False: 6]
  ------------------
  195|     90|            Ref<Sampler> sampler = prop.texture->sampler;
  196|       |
  197|     90|            aiString name(sampler->name);
  198|     90|            aiString id(sampler->id);
  199|       |
  200|     90|            mat->AddProperty(&name, AI_MATKEY_GLTF_MAPPINGNAME(texType, texSlot));
  201|     90|            mat->AddProperty(&id, AI_MATKEY_GLTF_MAPPINGID(texType, texSlot));
  202|       |
  203|     90|            aiTextureMapMode wrapS = ConvertWrappingMode(sampler->wrapS);
  204|     90|            aiTextureMapMode wrapT = ConvertWrappingMode(sampler->wrapT);
  205|     90|            mat->AddProperty(&wrapS, 1, AI_MATKEY_MAPPINGMODE_U(texType, texSlot));
  206|     90|            mat->AddProperty(&wrapT, 1, AI_MATKEY_MAPPINGMODE_V(texType, texSlot));
  207|       |
  208|     90|            if (sampler->magFilter != SamplerMagFilter::UNSET) {
  ------------------
  |  Branch (208:17): [True: 6, False: 84]
  ------------------
  209|      6|                mat->AddProperty(&sampler->magFilter, 1, AI_MATKEY_GLTF_MAPPINGFILTER_MAG(texType, texSlot));
  210|      6|            }
  211|       |
  212|     90|            if (sampler->minFilter != SamplerMinFilter::UNSET) {
  ------------------
  |  Branch (212:17): [True: 80, False: 10]
  ------------------
  213|     80|                mat->AddProperty(&sampler->minFilter, 1, AI_MATKEY_GLTF_MAPPINGFILTER_MIN(texType, texSlot));
  214|     80|            }
  215|     90|        } else {
  216|       |            // Use glTFv2 default sampler
  217|      6|            const aiTextureMapMode default_wrap = aiTextureMapMode_Wrap;
  218|      6|            mat->AddProperty(&default_wrap, 1, AI_MATKEY_MAPPINGMODE_U(texType, texSlot));
  219|       |            mat->AddProperty(&default_wrap, 1, AI_MATKEY_MAPPINGMODE_V(texType, texSlot));
  220|      6|        }
  221|     96|    }
  222|  27.2k|}
glTF2Importer.cpp:_ZL19ConvertWrappingModeN5glTF211SamplerWrapE:
  127|    180|static aiTextureMapMode ConvertWrappingMode(SamplerWrap gltfWrapMode) {
  128|    180|    switch (gltfWrapMode) {
  129|      0|        case SamplerWrap::Mirrored_Repeat:
  ------------------
  |  Branch (129:9): [True: 0, False: 180]
  ------------------
  130|      0|            return aiTextureMapMode_Mirror;
  131|       |
  132|      0|        case SamplerWrap::Clamp_To_Edge:
  ------------------
  |  Branch (132:9): [True: 0, False: 180]
  ------------------
  133|      0|            return aiTextureMapMode_Clamp;
  134|       |
  135|      0|        case SamplerWrap::UNSET:
  ------------------
  |  Branch (135:9): [True: 0, False: 180]
  ------------------
  136|    168|        case SamplerWrap::Repeat:
  ------------------
  |  Branch (136:9): [True: 168, False: 12]
  ------------------
  137|    180|        default:
  ------------------
  |  Branch (137:9): [True: 12, False: 168]
  ------------------
  138|    180|            break;
  139|    180|    }
  140|    180|    return aiTextureMapMode_Wrap;
  141|    180|}
glTF2Importer.cpp:_ZL26SetMaterialTexturePropertyRNSt3__16vectorIiNS_9allocatorIiEEEERN5glTF25AssetERNS5_17NormalTextureInfoEP10aiMaterial13aiTextureTypej:
  226|  3.40k|        unsigned int texSlot = 0) {
  227|  3.40k|    SetMaterialTextureProperty(embeddedTexIdxs, r, static_cast<TextureInfo>(prop), mat, texType, texSlot);
  228|       |
  229|  3.40k|    if (prop.texture && prop.texture->source) {
  ------------------
  |  Branch (229:9): [True: 0, False: 3.40k]
  |  Branch (229:25): [True: 0, False: 0]
  ------------------
  230|       |        mat->AddProperty(&prop.scale, 1, AI_MATKEY_GLTF_TEXTURE_SCALE(texType, texSlot));
  231|      0|    }
  232|  3.40k|}
glTF2Importer.cpp:_ZL26SetMaterialTexturePropertyRNSt3__16vectorIiNS_9allocatorIiEEEERN5glTF25AssetERNS5_20OcclusionTextureInfoEP10aiMaterial13aiTextureTypej:
  236|  3.40k|        unsigned int texSlot = 0) {
  237|  3.40k|    SetMaterialTextureProperty(embeddedTexIdxs, r, static_cast<TextureInfo>(prop), mat, texType, texSlot);
  238|       |
  239|  3.40k|    if (prop.texture && prop.texture->source) {
  ------------------
  |  Branch (239:9): [True: 0, False: 3.40k]
  |  Branch (239:25): [True: 0, False: 0]
  ------------------
  240|       |        mat->AddProperty(&prop.strength, 1, AI_MATKEY_GLTF_TEXTURE_STRENGTH(texType, texSlot));
  241|      0|    }
  242|  3.40k|}
glTF2Importer.cpp:_ZL24SetMaterialColorPropertyRN5glTF25AssetERA3_fP10aiMaterialPKcjj:
  151|  3.40k|        const char *pKey, unsigned int type, unsigned int idx) {
  152|  3.40k|    aiColor4D col;
  153|  3.40k|    CopyValue(prop, col);
  154|  3.40k|    mat->AddProperty(&col, 1, pKey, type, idx);
  155|  3.40k|}
glTF2Importer.cpp:_ZL18SetFaceAndAdvance1RP6aiFacejj:
  411|  1.76k|static inline void SetFaceAndAdvance1(aiFace *&face, unsigned int numVertices, unsigned int a) {
  412|  1.76k|    if (a >= numVertices) {
  ------------------
  |  Branch (412:9): [True: 745, False: 1.02k]
  ------------------
  413|    745|        return;
  414|    745|    }
  415|  1.02k|    face->mNumIndices = 1;
  416|  1.02k|    face->mIndices = new unsigned int[1];
  417|  1.02k|    face->mIndices[0] = a;
  418|  1.02k|    ++face;
  419|  1.02k|}
glTF2Importer.cpp:_ZL18SetFaceAndAdvance2RP6aiFacejjj:
  422|  8.99k|        unsigned int a, unsigned int b) {
  423|  8.99k|    if ((a >= numVertices) || (b >= numVertices)) {
  ------------------
  |  Branch (423:9): [True: 3.05k, False: 5.93k]
  |  Branch (423:31): [True: 617, False: 5.32k]
  ------------------
  424|  3.67k|        return;
  425|  3.67k|    }
  426|  5.32k|    face->mNumIndices = 2;
  427|  5.32k|    face->mIndices = new unsigned int[2];
  428|  5.32k|    face->mIndices[0] = a;
  429|  5.32k|    face->mIndices[1] = b;
  430|  5.32k|    ++face;
  431|  5.32k|}
glTF2Importer.cpp:_ZL18SetFaceAndAdvance3RP6aiFacejjjj:
  434|  37.3k|        unsigned int b, unsigned int c) {
  435|  37.3k|    if ((a >= numVertices) || (b >= numVertices) || (c >= numVertices)) {
  ------------------
  |  Branch (435:9): [True: 5.58k, False: 31.8k]
  |  Branch (435:31): [True: 2.50k, False: 29.2k]
  |  Branch (435:53): [True: 1.28k, False: 28.0k]
  ------------------
  436|  9.37k|        return;
  437|  9.37k|    }
  438|  28.0k|    face->mNumIndices = 3;
  439|  28.0k|    face->mIndices = new unsigned int[3];
  440|  28.0k|    face->mIndices[0] = a;
  441|  28.0k|    face->mIndices[1] = b;
  442|  28.0k|    face->mIndices[2] = c;
  443|  28.0k|    ++face;
  444|  28.0k|}
glTF2Importer.cpp:_ZL22CheckValidFacesIndicesP6aiFacejj:
  447|  1.40k|static inline bool CheckValidFacesIndices(aiFace *faces, unsigned nFaces, unsigned nVerts) {
  448|  35.7k|    for (unsigned i = 0; i < nFaces; ++i) {
  ------------------
  |  Branch (448:26): [True: 34.3k, False: 1.40k]
  ------------------
  449|   130k|        for (unsigned j = 0; j < faces[i].mNumIndices; ++j) {
  ------------------
  |  Branch (449:30): [True: 95.6k, False: 34.3k]
  ------------------
  450|  95.6k|            unsigned idx = faces[i].mIndices[j];
  451|  95.6k|            if (idx >= nVerts) {
  ------------------
  |  Branch (451:17): [True: 0, False: 95.6k]
  ------------------
  452|      0|                return false;
  453|      0|            }
  454|  95.6k|        }
  455|  34.3k|    }
  456|  1.40k|    return true;
  457|  1.40k|}
glTF2Importer.cpp:_ZL11GetNodeNameRKN5glTF24NodeE:
 1106|  8.25k|static std::string GetNodeName(const Node &node) {
 1107|  8.25k|    return node.name.empty() ? node.id : node.name;
  ------------------
  |  Branch (1107:12): [True: 0, False: 8.25k]
  ------------------
 1108|  8.25k|}
glTF2Importer.cpp:_ZL16GetNodeTransformR12aiMatrix4x4tIfERKN5glTF24NodeE:
 1005|  10.3k|static void GetNodeTransform(aiMatrix4x4 &matrix, const glTF2::Node &node) {
 1006|  10.3k|    if (node.matrix.isPresent) {
  ------------------
  |  Branch (1006:9): [True: 8.52k, False: 1.84k]
  ------------------
 1007|  8.52k|        CopyValue(node.matrix.value, matrix);
 1008|  8.52k|        return;
 1009|  8.52k|    }
 1010|       |
 1011|  1.84k|    if (node.translation.isPresent) {
  ------------------
  |  Branch (1011:9): [True: 0, False: 1.84k]
  ------------------
 1012|      0|        aiVector3D trans;
 1013|      0|        CopyValue(node.translation.value, trans);
 1014|      0|        aiMatrix4x4 t;
 1015|      0|        aiMatrix4x4::Translation(trans, t);
 1016|      0|        matrix = matrix * t;
 1017|      0|    }
 1018|       |
 1019|  1.84k|    if (node.rotation.isPresent) {
  ------------------
  |  Branch (1019:9): [True: 0, False: 1.84k]
  ------------------
 1020|      0|        aiQuaternion rot;
 1021|      0|        CopyValue(node.rotation.value, rot);
 1022|      0|        matrix = matrix * aiMatrix4x4(rot.GetMatrix());
 1023|      0|    }
 1024|       |
 1025|  1.84k|    if (node.scale.isPresent) {
  ------------------
  |  Branch (1025:9): [True: 0, False: 1.84k]
  ------------------
 1026|      0|        aiVector3D scal(1.f);
 1027|      0|        CopyValue(node.scale.value, scal);
 1028|      0|        aiMatrix4x4 s;
 1029|      0|        aiMatrix4x4::Scaling(scal, s);
 1030|      0|        matrix = matrix * s;
 1031|      0|    }
 1032|  1.84k|}
glTF2Importer.cpp:_ZL24BuildVertexWeightMappingRN5glTF24Mesh9PrimitiveERNSt3__16vectorINS4_I14aiVertexWeightNS3_9allocatorIS5_EEEENS6_IS8_EEEEPNS4_IjNS6_IjEEEE:
 1034|    274|static void BuildVertexWeightMapping(Mesh::Primitive &primitive, std::vector<std::vector<aiVertexWeight>> &map, std::vector<unsigned int>* vertexRemappingTablePtr) {
 1035|       |
 1036|    274|    Mesh::Primitive::Attributes &attr = primitive.attributes;
 1037|    274|    if (attr.weight.empty() || attr.joint.empty()) {
  ------------------
  |  Branch (1037:9): [True: 3, False: 271]
  |  Branch (1037:32): [True: 6, False: 265]
  ------------------
 1038|      9|        return;
 1039|      9|    }
 1040|    265|    if (attr.weight[0]->count != attr.joint[0]->count) {
  ------------------
  |  Branch (1040:9): [True: 14, False: 251]
  ------------------
 1041|     14|        return;
 1042|     14|    }
 1043|       |
 1044|    251|    size_t num_vertices = 0;
 1045|       |
 1046|    251|    struct Weights {
 1047|    251|        float values[4];
 1048|    251|    };
 1049|    251|    Weights **weights = new Weights*[attr.weight.size()];
 1050|    982|    for (size_t w = 0; w < attr.weight.size(); ++w) {
  ------------------
  |  Branch (1050:24): [True: 731, False: 251]
  ------------------
 1051|    731|        num_vertices = attr.weight[w]->ExtractData(weights[w], vertexRemappingTablePtr);
 1052|    731|    }
 1053|       |
 1054|    251|    struct Indices8 {
 1055|    251|        uint8_t values[4];
 1056|    251|    };
 1057|    251|    struct Indices16 {
 1058|    251|        uint16_t values[4];
 1059|    251|    };
 1060|    251|    Indices8 **indices8 = nullptr;
 1061|    251|    Indices16 **indices16 = nullptr;
 1062|    251|    if (attr.joint[0]->GetElementSize() == 4) {
  ------------------
  |  Branch (1062:9): [True: 34, False: 217]
  ------------------
 1063|     34|        indices8 = new Indices8*[attr.joint.size()];
 1064|    110|        for (size_t j = 0; j < attr.joint.size(); ++j) {
  ------------------
  |  Branch (1064:28): [True: 76, False: 34]
  ------------------
 1065|     76|            attr.joint[j]->ExtractData(indices8[j], vertexRemappingTablePtr);
 1066|     76|        }
 1067|    217|    } else {
 1068|    217|        indices16 = new Indices16 *[attr.joint.size()];
 1069|    829|        for (size_t j = 0; j < attr.joint.size(); ++j) {
  ------------------
  |  Branch (1069:28): [True: 612, False: 217]
  ------------------
 1070|    612|            attr.joint[j]->ExtractData(indices16[j], vertexRemappingTablePtr);
 1071|    612|        }
 1072|    217|    }
 1073|       |
 1074|       |    // No indices are an invalid usecase
 1075|    251|    if (nullptr == indices8 && nullptr == indices16) {
  ------------------
  |  Branch (1075:9): [True: 199, False: 52]
  |  Branch (1075:32): [True: 0, False: 199]
  ------------------
 1076|       |        // Something went completely wrong!
 1077|      0|        ai_assert(false);
 1078|      0|        return;
 1079|      0|    }
 1080|       |
 1081|    870|    for (size_t w = 0; w < attr.weight.size(); ++w) {
  ------------------
  |  Branch (1081:24): [True: 619, False: 251]
  ------------------
 1082|  2.76k|        for (size_t i = 0; i < num_vertices; ++i) {
  ------------------
  |  Branch (1082:28): [True: 2.14k, False: 619]
  ------------------
 1083|  10.7k|            for (int j = 0; j < 4; ++j) {
  ------------------
  |  Branch (1083:29): [True: 8.56k, False: 2.14k]
  ------------------
 1084|  8.56k|                const unsigned int bone = (indices8 != nullptr) ? indices8[w][i].values[j] : indices16[w][i].values[j];
  ------------------
  |  Branch (1084:43): [True: 408, False: 8.16k]
  ------------------
 1085|  8.56k|                const float weight = weights[w][i].values[j];
 1086|  8.56k|                if (weight > 0 && bone < map.size()) {
  ------------------
  |  Branch (1086:21): [True: 5.64k, False: 2.92k]
  |  Branch (1086:35): [True: 3.59k, False: 2.04k]
  ------------------
 1087|  3.59k|                    map[bone].reserve(8);
 1088|  3.59k|                    map[bone].emplace_back(static_cast<unsigned int>(i), weight);
 1089|  3.59k|                }
 1090|  8.56k|            }
 1091|  2.14k|        }
 1092|    619|    }
 1093|       |
 1094|    870|    for (size_t w = 0; w < attr.weight.size(); ++w) {
  ------------------
  |  Branch (1094:24): [True: 619, False: 251]
  ------------------
 1095|    619|        delete[] weights[w];
 1096|    619|        if(indices8)
  ------------------
  |  Branch (1096:12): [True: 36, False: 583]
  ------------------
 1097|     36|            delete[] indices8[w];
 1098|    619|        if (indices16)
  ------------------
  |  Branch (1098:13): [True: 583, False: 36]
  ------------------
 1099|    583|            delete[] indices16[w];
 1100|    619|    }
 1101|    251|    delete[] weights;
 1102|    251|    delete[] indices8;
 1103|    251|    delete[] indices16;
 1104|    251|}
glTF2Importer.cpp:_ZL21countEmbeddedTexturesRN5glTF25AssetE:
 1679|  2.00k|static unsigned int countEmbeddedTextures(glTF2::Asset &r) {
 1680|  2.00k|    unsigned int numEmbeddedTexs = 0;
 1681|  2.05k|    for (size_t i = 0; i < r.images.Size(); ++i) {
  ------------------
  |  Branch (1681:24): [True: 48, False: 2.00k]
  ------------------
 1682|     48|        if (r.images[i].HasData()) {
  ------------------
  |  Branch (1682:13): [True: 47, False: 1]
  ------------------
 1683|     47|            numEmbeddedTexs += 1;
 1684|     47|        }
 1685|     48|    }
 1686|       |
 1687|  2.00k|    return numEmbeddedTexs;
 1688|  2.00k|}
_Z22GetVertexColorsForTypeIhEP9aiColor4tIfEN10glTFCommon3RefIN5glTF28AccessorEEEPNSt3__16vectorIjNS8_9allocatorIjEEEE:
  461|      7|aiColor4D *GetVertexColorsForType(Ref<Accessor> input, std::vector<unsigned int> *vertexRemappingTable) {
  462|      7|    constexpr float max = std::numeric_limits<T>::max();
  463|      7|    aiColor4t<T> *colors;
  464|      7|    size_t count = input->ExtractData(colors, vertexRemappingTable);
  465|      7|    auto output = new aiColor4D[count];
  466|     24|    for (size_t i = 0; i < count; i++) {
  ------------------
  |  Branch (466:24): [True: 17, False: 7]
  ------------------
  467|     17|        output[i] = aiColor4D(
  468|     17|                colors[i].r / max, colors[i].g / max,
  469|     17|                colors[i].b / max, colors[i].a / max);
  470|     17|    }
  471|      7|    delete[] colors;
  472|      7|    return output;
  473|      7|}
_Z22GetVertexColorsForTypeItEP9aiColor4tIfEN10glTFCommon3RefIN5glTF28AccessorEEEPNSt3__16vectorIjNS8_9allocatorIjEEEE:
  461|      8|aiColor4D *GetVertexColorsForType(Ref<Accessor> input, std::vector<unsigned int> *vertexRemappingTable) {
  462|      8|    constexpr float max = std::numeric_limits<T>::max();
  463|      8|    aiColor4t<T> *colors;
  464|      8|    size_t count = input->ExtractData(colors, vertexRemappingTable);
  465|      8|    auto output = new aiColor4D[count];
  466|     25|    for (size_t i = 0; i < count; i++) {
  ------------------
  |  Branch (466:24): [True: 17, False: 8]
  ------------------
  467|     17|        output[i] = aiColor4D(
  468|     17|                colors[i].r / max, colors[i].g / max,
  469|     17|                colors[i].b / max, colors[i].a / max);
  470|     17|    }
  471|      8|    delete[] colors;
  472|      8|    return output;
  473|      8|}

_ZN6Assimp13glTF2ImporterD2Ev:
   62|  3.48k|    ~glTF2Importer() override = default;

_ZN10glTFCommon10ReadHelperIbE4ReadERN9rapidjson12GenericValueINS2_4UTF8IcEENS2_19MemoryPoolAllocatorINS2_12CrtAllocatorEEEEERb:
  289|    953|    static bool Read(Value &val, bool &out) {
  290|    953|        return val.IsBool() ? out = val.GetBool(), true : false;
  ------------------
  |  Branch (290:16): [True: 928, False: 25]
  ------------------
  291|    953|    }
_ZN10glTFCommon10ReadHelperIfE4ReadERN9rapidjson12GenericValueINS2_4UTF8IcEENS2_19MemoryPoolAllocatorINS2_12CrtAllocatorEEEEERf:
  296|  1.29k|    static bool Read(Value &val, float &out) {
  297|  1.29k|        return val.IsNumber() ? out = static_cast<float>(val.GetDouble()), true : false;
  ------------------
  |  Branch (297:16): [True: 1.25k, False: 34]
  ------------------
  298|  1.29k|    }
_ZN10glTFCommon10ReadHelperIPKcE4ReadERN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEERS2_:
  315|  6.80k|    static bool Read(Value &val, const char *&out) {
  316|  6.80k|        return val.IsString() ? (out = val.GetString(), true) : false;
  ------------------
  |  Branch (316:16): [True: 6.80k, False: 1]
  ------------------
  317|  6.80k|    }
_ZN10glTFCommon10ReadHelperINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEE4ReadERN9rapidjson12GenericValueINS9_4UTF8IcEENS9_19MemoryPoolAllocatorINS9_12CrtAllocatorEEEEERS7_:
  322|  25.9k|    static bool Read(Value &val, std::string &out) {
  323|  25.9k|        return val.IsString() ? (out = std::string(val.GetString(), val.GetStringLength()), true) : false;
  ------------------
  |  Branch (323:16): [True: 25.8k, False: 21]
  ------------------
  324|  25.9k|    }
_ZN10glTFCommon10ReadHelperImE4ReadERN9rapidjson12GenericValueINS2_4UTF8IcEENS2_19MemoryPoolAllocatorINS2_12CrtAllocatorEEEEERm:
  336|  18.8k|    static bool Read(Value &val, uint64_t &out) {
  337|  18.8k|        return val.IsUint64() ? out = val.GetUint64(), true : false;
  ------------------
  |  Branch (337:16): [True: 18.8k, False: 5]
  ------------------
  338|  18.8k|    }
_ZN10glTFCommon9CopyValueERA3_KfR9aiColor4tIfE:
  138|  3.40k|inline void CopyValue(const glTFCommon::vec3 &v, aiColor4D &out) {
  139|  3.40k|    out.r = v[0];
  140|  3.40k|    out.g = v[1];
  141|  3.40k|    out.b = v[2];
  142|  3.40k|    out.a = 1.0;
  143|  3.40k|}
_ZN10glTFCommon9CopyValueERA4_KfR9aiColor4tIfE:
  145|  6.80k|inline void CopyValue(const glTFCommon::vec4 &v, aiColor4D &out) {
  146|  6.80k|    out.r = v[0];
  147|  6.80k|    out.g = v[1];
  148|  6.80k|    out.b = v[2];
  149|  6.80k|    out.a = v[3];
  150|  6.80k|}
_ZN10glTFCommon9CopyValueERA16_KfR12aiMatrix4x4tIfE:
  177|  10.7k|inline void CopyValue(const glTFCommon::mat4 &v, aiMatrix4x4 &o) {
  178|  10.7k|    o.a1 = v[0];
  179|  10.7k|    o.b1 = v[1];
  180|  10.7k|    o.c1 = v[2];
  181|  10.7k|    o.d1 = v[3];
  182|  10.7k|    o.a2 = v[4];
  183|  10.7k|    o.b2 = v[5];
  184|  10.7k|    o.c2 = v[6];
  185|  10.7k|    o.d2 = v[7];
  186|  10.7k|    o.a3 = v[8];
  187|  10.7k|    o.b3 = v[9];
  188|  10.7k|    o.c3 = v[10];
  189|  10.7k|    o.d3 = v[11];
  190|  10.7k|    o.a4 = v[12];
  191|  10.7k|    o.b4 = v[13];
  192|  10.7k|    o.c4 = v[14];
  193|  10.7k|    o.d4 = v[15];
  194|  10.7k|}
_ZN10glTFCommon10FindMemberERN9rapidjson12GenericValueINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEEEEPKc:
  386|  8.69k|inline Value *FindMember(Value &val, const char *id) {
  387|  8.69k|    if (!val.IsObject()) {
  ------------------
  |  Branch (387:9): [True: 0, False: 8.69k]
  ------------------
  388|      0|        return nullptr;
  389|      0|    }
  390|  8.69k|    Value::MemberIterator it = val.FindMember(id);
  391|  8.69k|    return (it != val.MemberEnd()) ? &it->value : nullptr;
  ------------------
  |  Branch (391:12): [True: 1.59k, False: 7.09k]
  ------------------
  392|  8.69k|}
_ZN10glTFCommon19FindStringInContextERN9rapidjson12GenericValueINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEEEEPKcSA_SA_:
  405|  6.95k|inline Value *FindStringInContext(Value &val, const char *memberId, const char *context, const char *extraContext = nullptr) {
  406|  6.95k|    if (!val.IsObject()) {
  ------------------
  |  Branch (406:9): [True: 0, False: 6.95k]
  ------------------
  407|      0|        return nullptr;
  408|      0|    }
  409|  6.95k|    Value::MemberIterator it = val.FindMember(memberId);
  410|  6.95k|    if (it == val.MemberEnd()) {
  ------------------
  |  Branch (410:9): [True: 2.83k, False: 4.12k]
  ------------------
  411|  2.83k|        return nullptr;
  412|  2.83k|    }
  413|  4.12k|    if (!it->value.IsString()) {
  ------------------
  |  Branch (413:9): [True: 23, False: 4.10k]
  ------------------
  414|     23|        throwUnexpectedTypeError("string", memberId, context, extraContext);
  415|     23|    }
  416|  4.12k|    return &it->value;
  417|  6.95k|}
_ZN10glTFCommon17FindUIntInContextERN9rapidjson12GenericValueINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEEEEPKcSA_SA_:
  433|  61.0k|inline Value *FindUIntInContext(Value &val, const char *memberId, const char *context, const char *extraContext = nullptr) {
  434|  61.0k|    if (!val.IsObject()) {
  ------------------
  |  Branch (434:9): [True: 2, False: 61.0k]
  ------------------
  435|      2|        return nullptr;
  436|      2|    }
  437|  61.0k|    Value::MemberIterator it = val.FindMember(memberId);
  438|  61.0k|    if (it == val.MemberEnd()) {
  ------------------
  |  Branch (438:9): [True: 32.6k, False: 28.3k]
  ------------------
  439|  32.6k|        return nullptr;
  440|  32.6k|    }
  441|  28.3k|    if (!it->value.IsUint()) {
  ------------------
  |  Branch (441:9): [True: 29, False: 28.3k]
  ------------------
  442|     29|        throwUnexpectedTypeError("uint", memberId, context, extraContext);
  443|     29|    }
  444|  28.3k|    return &it->value;
  445|  61.0k|}
_ZN10glTFCommon18FindArrayInContextERN9rapidjson12GenericValueINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEEEEPKcSA_SA_:
  447|  71.9k|inline Value *FindArrayInContext(Value &val, const char *memberId, const char *context, const char *extraContext = nullptr) {
  448|  71.9k|    if (!val.IsObject()) {
  ------------------
  |  Branch (448:9): [True: 1, False: 71.9k]
  ------------------
  449|      1|        return nullptr;
  450|      1|    }
  451|  71.9k|    Value::MemberIterator it = val.FindMember(memberId);
  452|  71.9k|    if (it == val.MemberEnd()) {
  ------------------
  |  Branch (452:9): [True: 34.3k, False: 37.6k]
  ------------------
  453|  34.3k|        return nullptr;
  454|  34.3k|    }
  455|  37.6k|    if (!it->value.IsArray()) {
  ------------------
  |  Branch (455:9): [True: 35, False: 37.5k]
  ------------------
  456|     35|        throwUnexpectedTypeError("array", memberId, context, extraContext);
  457|     35|    }
  458|  37.6k|    return &it->value;
  459|  71.9k|}
_ZN10glTFCommon19FindObjectInContextERN9rapidjson12GenericValueINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEEEEPKcSA_SA_:
  461|   102k|inline Value *FindObjectInContext(Value &val, const char * memberId, const char *context, const char *extraContext = nullptr) {
  462|   102k|    if (!val.IsObject()) {
  ------------------
  |  Branch (462:9): [True: 2, False: 102k]
  ------------------
  463|      2|        return nullptr;
  464|      2|    }
  465|   102k|    Value::MemberIterator it = val.FindMember(memberId);
  466|   102k|    if (it == val.MemberEnd()) {
  ------------------
  |  Branch (466:9): [True: 86.7k, False: 15.6k]
  ------------------
  467|  86.7k|        return nullptr;
  468|  86.7k|    }
  469|  15.6k|    if (!it->value.IsObject()) {
  ------------------
  |  Branch (469:9): [True: 42, False: 15.5k]
  ------------------
  470|     42|        ASSIMP_LOG_ERROR("Member \"", memberId, "\" was not of type \"", context, "\" when reading ", extraContext);
  471|     42|        return nullptr;
  472|     42|   }
  473|  15.5k|    return &it->value;
  474|  15.6k|}
_ZN10glTFCommon10FindStringERN9rapidjson15GenericDocumentINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEES5_EEPKc:
  487|    192|inline Value *FindString(Document &doc, const char *memberId) {
  488|    192|    return FindStringInContext(doc, memberId, "the document");
  489|    192|}
_ZN10glTFCommon8FindUIntERN9rapidjson15GenericDocumentINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEES5_EEPKc:
  495|  2.29k|inline Value *FindUInt(Document &doc, const char *memberId) {
  496|  2.29k|    return FindUIntInContext(doc, memberId, "the document");
  497|  2.29k|}
_ZN10glTFCommon9FindArrayERN9rapidjson15GenericDocumentINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEES5_EEPKc:
  499|  11.1k|inline Value *FindArray(Document &val, const char *memberId) {
  500|  11.1k|    return FindArrayInContext(val, memberId, "the document");
  501|  11.1k|}
_ZN10glTFCommon10FindObjectERN9rapidjson15GenericDocumentINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEES5_EEPKc:
  503|  10.4k|inline Value *FindObject(Document &doc, const char *memberId) {
  504|  10.4k|    return FindObjectInContext(doc, memberId, "the document");
  505|  10.4k|}
_ZN10glTFCommon10FindStringERN9rapidjson12GenericValueINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEEEEPKc:
  511|    620|inline Value *FindString(Value &val, const char *id) {
  512|    620|    Value::MemberIterator it = val.FindMember(id);
  513|    620|    return (it != val.MemberEnd() && it->value.IsString()) ? &it->value : nullptr;
  ------------------
  |  Branch (513:13): [True: 582, False: 38]
  |  Branch (513:38): [True: 572, False: 10]
  ------------------
  514|    620|}
_ZN10glTFCommon10FindObjectERN9rapidjson12GenericValueINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEEEEPKc:
  516|  3.11k|inline Value *FindObject(Value &val, const char *id) {
  517|  3.11k|    Value::MemberIterator it = val.FindMember(id);
  518|  3.11k|    return (it != val.MemberEnd() && it->value.IsObject()) ? &it->value : nullptr;
  ------------------
  |  Branch (518:13): [True: 78, False: 3.03k]
  |  Branch (518:38): [True: 8, False: 70]
  ------------------
  519|  3.11k|}
_ZN10glTFCommon10FindNumberERN9rapidjson12GenericValueINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEEEEPKc:
  526|     48|inline Value *FindNumber(Value &val, const char *id) {
  527|     48|    Value::MemberIterator it = val.FindMember(id);
  528|     48|    return (it != val.MemberEnd() && it->value.IsNumber()) ? &it->value : nullptr;
  ------------------
  |  Branch (528:13): [True: 10, False: 38]
  |  Branch (528:38): [True: 8, False: 2]
  ------------------
  529|     48|}
_ZN10glTFCommon24throwUnexpectedTypeErrorILi7EEEvRAT__KcPS1_S4_S4_:
  395|     23|inline void throwUnexpectedTypeError(const char (&expectedTypeName)[N], const char *memberId, const char *context, const char *extraContext) {
  396|     23|    std::string fullContext = context;
  397|     23|    if (extraContext && (strlen(extraContext) > 0)) {
  ------------------
  |  Branch (397:9): [True: 1, False: 22]
  |  Branch (397:25): [True: 0, False: 1]
  ------------------
  398|      0|        fullContext = fullContext + " (" + extraContext + ")";
  399|      0|    }
  400|     23|    throw DeadlyImportError("Member \"", memberId, "\" was not of type \"", expectedTypeName, "\" when reading ", fullContext);
  401|     23|}
_ZN10glTFCommon24throwUnexpectedTypeErrorILi5EEEvRAT__KcPS1_S4_S4_:
  395|     29|inline void throwUnexpectedTypeError(const char (&expectedTypeName)[N], const char *memberId, const char *context, const char *extraContext) {
  396|     29|    std::string fullContext = context;
  397|     29|    if (extraContext && (strlen(extraContext) > 0)) {
  ------------------
  |  Branch (397:9): [True: 21, False: 8]
  |  Branch (397:25): [True: 11, False: 10]
  ------------------
  398|     11|        fullContext = fullContext + " (" + extraContext + ")";
  399|     11|    }
  400|     29|    throw DeadlyImportError("Member \"", memberId, "\" was not of type \"", expectedTypeName, "\" when reading ", fullContext);
  401|     29|}
_ZN10glTFCommon24throwUnexpectedTypeErrorILi6EEEvRAT__KcPS1_S4_S4_:
  395|     35|inline void throwUnexpectedTypeError(const char (&expectedTypeName)[N], const char *memberId, const char *context, const char *extraContext) {
  396|     35|    std::string fullContext = context;
  397|     35|    if (extraContext && (strlen(extraContext) > 0)) {
  ------------------
  |  Branch (397:9): [True: 9, False: 26]
  |  Branch (397:25): [True: 7, False: 2]
  ------------------
  398|      7|        fullContext = fullContext + " (" + extraContext + ")";
  399|      7|    }
  400|     35|    throw DeadlyImportError("Member \"", memberId, "\" was not of type \"", expectedTypeName, "\" when reading ", fullContext);
  401|     35|}
_ZN10glTFCommon10ReadHelperINS_8NullableINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEEE4ReadERN9rapidjson12GenericValueINSB_4UTF8IcEENSB_19MemoryPoolAllocatorINSB_12CrtAllocatorEEEEERS9_:
  329|  7.50k|    static bool Read(Value &val, Nullable<T> &out) {
  330|  7.50k|        return out.isPresent = ReadHelper<T>::Read(val, out.value);
  331|  7.50k|    }
_ZNK10glTFCommon3RefIN5glTF26BufferEEcvbEv:
  269|  17.0k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 12.5k, False: 4.49k]
  |  Branch (269:57): [True: 12.5k, False: 0]
  ------------------
_ZN10glTFCommon10ReadHelperIjE4ReadERN9rapidjson12GenericValueINS2_4UTF8IcEENS2_19MemoryPoolAllocatorINS2_12CrtAllocatorEEEEERj:
  282|  1.63k|    static bool Read(Value &val, T &out) {
  283|  1.63k|        return val.IsInt() ? out = static_cast<T>(val.GetInt()), true : false;
  ------------------
  |  Branch (283:16): [True: 1.63k, False: 1]
  ------------------
  284|  1.63k|    }
_ZN10glTFCommon3RefIN5glTF26BufferEEptEv:
  271|  31.8k|    T *operator->() { return (*vector)[index]; }
_ZN10glTFCommon3RefIN5glTF210BufferViewEEptEv:
  271|   130k|    T *operator->() { return (*vector)[index]; }
_ZN10glTFCommon10ReadHelperIN5glTF213ComponentTypeEE4ReadERN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEERS2_:
  282|  5.34k|    static bool Read(Value &val, T &out) {
  283|  5.34k|        return val.IsInt() ? out = static_cast<T>(val.GetInt()), true : false;
  ------------------
  |  Branch (283:16): [True: 5.33k, False: 12]
  ------------------
  284|  5.34k|    }
_ZNK10glTFCommon3RefIN5glTF210BufferViewEEcvbEv:
  269|  60.6k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 60.4k, False: 232]
  |  Branch (269:57): [True: 60.4k, False: 0]
  ------------------
_ZN10glTFCommon10ReadHelperIN5glTF216SamplerMagFilterEE4ReadERN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEERS2_:
  282|      5|    static bool Read(Value &val, T &out) {
  283|      5|        return val.IsInt() ? out = static_cast<T>(val.GetInt()), true : false;
  ------------------
  |  Branch (283:16): [True: 4, False: 1]
  ------------------
  284|      5|    }
_ZN10glTFCommon10ReadHelperIN5glTF216SamplerMinFilterEE4ReadERN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEERS2_:
  282|     55|    static bool Read(Value &val, T &out) {
  283|     55|        return val.IsInt() ? out = static_cast<T>(val.GetInt()), true : false;
  ------------------
  |  Branch (283:16): [True: 54, False: 1]
  ------------------
  284|     55|    }
_ZN10glTFCommon10ReadHelperIN5glTF211SamplerWrapEE4ReadERN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEERS2_:
  282|    109|    static bool Read(Value &val, T &out) {
  283|    109|        return val.IsInt() ? out = static_cast<T>(val.GetInt()), true : false;
  ------------------
  |  Branch (283:16): [True: 106, False: 3]
  ------------------
  284|    109|    }
_ZN10glTFCommon10ReadHelperIA4_fE4ReadERN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEERS1_:
  303|    927|    static bool Read(Value &val, float (&out)[N]) {
  304|    927|        if (!val.IsArray() || val.Size() != N) return false;
  ------------------
  |  Branch (304:13): [True: 1, False: 926]
  |  Branch (304:31): [True: 2, False: 924]
  ------------------
  305|  4.62k|        for (unsigned int i = 0; i < N; ++i) {
  ------------------
  |  Branch (305:34): [True: 3.69k, False: 924]
  ------------------
  306|  3.69k|            if (val[i].IsNumber())
  ------------------
  |  Branch (306:17): [True: 3.69k, False: 0]
  ------------------
  307|  3.69k|                out[i] = static_cast<float>(val[i].GetDouble());
  308|  3.69k|        }
  309|    924|        return true;
  310|    927|    }
_ZN10glTFCommon10ReadHelperIA3_fE4ReadERN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEERS1_:
  303|  1.01k|    static bool Read(Value &val, float (&out)[N]) {
  304|  1.01k|        if (!val.IsArray() || val.Size() != N) return false;
  ------------------
  |  Branch (304:13): [True: 1, False: 1.01k]
  |  Branch (304:31): [True: 8, False: 1.00k]
  ------------------
  305|  4.01k|        for (unsigned int i = 0; i < N; ++i) {
  ------------------
  |  Branch (305:34): [True: 3.01k, False: 1.00k]
  ------------------
  306|  3.01k|            if (val[i].IsNumber())
  ------------------
  |  Branch (306:17): [True: 3.01k, False: 0]
  ------------------
  307|  3.01k|                out[i] = static_cast<float>(val[i].GetDouble());
  308|  3.01k|        }
  309|  1.00k|        return true;
  310|  1.01k|    }
_ZN10glTFCommon10ReadHelperIN5glTF213PrimitiveModeEE4ReadERN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEERS2_:
  282|  1.78k|    static bool Read(Value &val, T &out) {
  283|  1.78k|        return val.IsInt() ? out = static_cast<T>(val.GetInt()), true : false;
  ------------------
  |  Branch (283:16): [True: 1.78k, False: 2]
  ------------------
  284|  1.78k|    }
_ZNK10glTFCommon3RefIN5glTF24NodeEEcvbEv:
  269|  14.1k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 14.1k, False: 0]
  |  Branch (269:57): [True: 14.1k, False: 0]
  ------------------
_ZN10glTFCommon10ReadHelperINS_8NullableIA16_fEEE4ReadERN9rapidjson12GenericValueINS5_4UTF8IcEENS5_19MemoryPoolAllocatorINS5_12CrtAllocatorEEEEERS3_:
  329|  9.12k|    static bool Read(Value &val, Nullable<T> &out) {
  330|  9.12k|        return out.isPresent = ReadHelper<T>::Read(val, out.value);
  331|  9.12k|    }
_ZN10glTFCommon10ReadHelperIA16_fE4ReadERN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEERS1_:
  303|  9.12k|    static bool Read(Value &val, float (&out)[N]) {
  304|  9.12k|        if (!val.IsArray() || val.Size() != N) return false;
  ------------------
  |  Branch (304:13): [True: 0, False: 9.12k]
  |  Branch (304:31): [True: 109, False: 9.01k]
  ------------------
  305|   153k|        for (unsigned int i = 0; i < N; ++i) {
  ------------------
  |  Branch (305:34): [True: 144k, False: 9.01k]
  ------------------
  306|   144k|            if (val[i].IsNumber())
  ------------------
  |  Branch (306:17): [True: 144k, False: 3]
  ------------------
  307|   144k|                out[i] = static_cast<float>(val[i].GetDouble());
  308|   144k|        }
  309|  9.01k|        return true;
  310|  9.12k|    }
_ZN10glTFCommon10ReadHelperINS_8NullableIA4_fEEE4ReadERN9rapidjson12GenericValueINS5_4UTF8IcEENS5_19MemoryPoolAllocatorINS5_12CrtAllocatorEEEEERS3_:
  329|      1|    static bool Read(Value &val, Nullable<T> &out) {
  330|      1|        return out.isPresent = ReadHelper<T>::Read(val, out.value);
  331|      1|    }
_ZNK10glTFCommon3RefIN5glTF24MeshEEcvbEv:
  269|  1.78k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 1.78k, False: 0]
  |  Branch (269:57): [True: 1.78k, False: 0]
  ------------------
_ZNK10glTFCommon3RefIN5glTF26CameraEEcvbEv:
  269|  8.12k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 0, False: 8.12k]
  |  Branch (269:57): [True: 0, False: 0]
  ------------------
_ZNK10glTFCommon3RefIN5glTF25LightEEcvbEv:
  269|  8.12k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 0, False: 8.12k]
  |  Branch (269:57): [True: 0, False: 0]
  ------------------
_ZN10glTFCommon3RefIN5glTF25SceneEEptEv:
  271|  8.43k|    T *operator->() { return (*vector)[index]; }
_ZN10glTFCommon3RefIN4glTF6BufferEEC2Ev:
  261|  4.58k|            vector(nullptr),
  262|  4.58k|            index(0) {}
_ZN10glTFCommon3RefIN4glTF5SceneEEC2Ev:
  261|  4.58k|            vector(nullptr),
  262|  4.58k|            index(0) {}
_ZN10glTFCommon3RefIN4glTF6BufferEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|  2.44k|            vector(&vec),
  265|  2.44k|            index(idx) {}
glTFImporter.cpp:_ZN10glTFCommonL10ReadMemberINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEEbRN9rapidjson12GenericValueINS8_4UTF8IcEENS8_19MemoryPoolAllocatorINS8_12CrtAllocatorEEEEEPKcRT_:
  369|  1.24k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  1.24k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 1.24k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  1.24k|    Value::MemberIterator it = obj.FindMember(id);
  374|  1.24k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 192, False: 1.04k]
  ------------------
  375|    192|        return ReadHelper<T>::Read(it->value, out);
  376|    192|    }
  377|  1.04k|    return false;
  378|  1.24k|}
glTFImporter.cpp:_ZN10glTFCommonL15MemberOrDefaultIbEET_RN9rapidjson12GenericValueINS2_4UTF8IcEENS2_19MemoryPoolAllocatorINS2_12CrtAllocatorEEEEEPKcS1_:
  381|    620|inline static T MemberOrDefault(Value &obj, const char *id, T defaultValue) {
  382|    620|    T out;
  383|    620|    return ReadMember(obj, id, out) ? out : defaultValue;
  ------------------
  |  Branch (383:12): [True: 0, False: 620]
  ------------------
  384|    620|}
glTFImporter.cpp:_ZN10glTFCommonL10ReadMemberIbEEbRN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEEPKcRT_:
  369|    620|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|    620|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 620]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|    620|    Value::MemberIterator it = obj.FindMember(id);
  374|    620|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 24, False: 596]
  ------------------
  375|     24|        return ReadHelper<T>::Read(it->value, out);
  376|     24|    }
  377|    596|    return false;
  378|    620|}
_ZN10glTFCommon8NullableIA16_fEC2Ev:
  246|  11.9k|            isPresent(false) {}
_ZN10glTFCommon8NullableIA3_fEC2Ev:
  246|  23.1k|            isPresent(false) {}
_ZN10glTFCommon8NullableIA4_fEC2Ev:
  246|  11.5k|            isPresent(false) {}
_ZN10glTFCommon3RefIN4glTF6BufferEEptEv:
  271|  2.44k|    T *operator->() { return (*vector)[index]; }
_ZNK10glTFCommon3RefIN4glTF5SceneEEcvbEv:
  269|     89|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 0, False: 89]
  |  Branch (269:57): [True: 0, False: 0]
  ------------------
_ZNK10glTFCommon3RefIN5glTF27TextureEEcvbEv:
  269|  34.0k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 118, False: 33.8k]
  |  Branch (269:57): [True: 118, False: 0]
  ------------------
_ZN10glTFCommon3RefIN5glTF27TextureEEptEv:
  271|    496|    T *operator->() { return (*vector)[index]; }
_ZNK10glTFCommon3RefIN5glTF25ImageEEcvbEv:
  269|    118|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 96, False: 22]
  |  Branch (269:57): [True: 96, False: 0]
  ------------------
_ZN10glTFCommon3RefIN5glTF25ImageEEptEv:
  271|     96|    T *operator->() { return (*vector)[index]; }
_ZNK10glTFCommon3RefIN5glTF27SamplerEEcvbEv:
  269|     96|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 90, False: 6]
  |  Branch (269:57): [True: 90, False: 0]
  ------------------
_ZN10glTFCommon3RefIN5glTF27SamplerEEptEv:
  271|    626|    T *operator->() { return (*vector)[index]; }
_ZN10glTFCommon3RefIN5glTF25SceneEEC2Ev:
  261|  6.79k|            vector(nullptr),
  262|  6.79k|            index(0) {}
_ZN10glTFCommon3RefIN5glTF26BufferEEC2Ev:
  261|  13.5k|            vector(nullptr),
  262|  13.5k|            index(0) {}
_ZN10glTFCommon8NullableINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEC2Ev:
  246|  70.9k|            isPresent(false) {}
_ZN10glTFCommon8NullableIdEC2Ev:
  246|  70.9k|            isPresent(false) {}
_ZN10glTFCommon8NullableImEC2Ev:
  246|  70.9k|            isPresent(false) {}
_ZN10glTFCommon8NullableIlEC2Ev:
  246|  70.9k|            isPresent(false) {}
_ZN10glTFCommon8NullableIbEC2Ev:
  246|  70.9k|            isPresent(false) {}
_ZN10glTFCommon8NullableINSt3__16vectorIN5glTF215CustomExtensionENS1_9allocatorIS4_EEEEEC2Ev:
  246|  70.9k|            isPresent(false) {}
_ZN10glTFCommon3RefIN5glTF26BufferEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|  11.1k|            vector(&vec),
  265|  11.1k|            index(idx) {}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEEbRN9rapidjson12GenericValueINS8_4UTF8IcEENS8_19MemoryPoolAllocatorINS8_12CrtAllocatorEEEEEPKcRT_:
  369|  42.1k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  42.1k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 42.1k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  42.1k|    Value::MemberIterator it = obj.FindMember(id);
  374|  42.1k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 18.2k, False: 23.9k]
  ------------------
  375|  18.2k|        return ReadHelper<T>::Read(it->value, out);
  376|  18.2k|    }
  377|  23.9k|    return false;
  378|  42.1k|}
_ZN10glTFCommon3RefIN5glTF27TextureEEC2Ev:
  261|  60.2k|            vector(nullptr),
  262|  60.2k|            index(0) {}
_ZN10glTFCommon8NullableIN5glTF221PbrSpecularGlossinessEEC2Ev:
  246|  3.54k|            isPresent(false) {}
_ZN10glTFCommon8NullableIN5glTF216MaterialSpecularEEC2Ev:
  246|  3.54k|            isPresent(false) {}
_ZN10glTFCommon8NullableIN5glTF213MaterialSheenEEC2Ev:
  246|  3.54k|            isPresent(false) {}
_ZN10glTFCommon8NullableIN5glTF217MaterialClearcoatEEC2Ev:
  246|  3.54k|            isPresent(false) {}
_ZN10glTFCommon8NullableIN5glTF220MaterialTransmissionEEC2Ev:
  246|  3.54k|            isPresent(false) {}
_ZN10glTFCommon8NullableIN5glTF214MaterialVolumeEEC2Ev:
  246|  3.54k|            isPresent(false) {}
_ZN10glTFCommon8NullableIN5glTF211MaterialIOREEC2Ev:
  246|  3.54k|            isPresent(false) {}
_ZN10glTFCommon8NullableIN5glTF224MaterialEmissiveStrengthEEC2Ev:
  246|  3.54k|            isPresent(false) {}
_ZN10glTFCommon8NullableIN5glTF218MaterialAnisotropyEEC2Ev:
  246|  3.54k|            isPresent(false) {}
_ZNK10glTFCommon3RefIN5glTF25ImageEE8GetIndexEv:
  267|     96|    inline unsigned int GetIndex() const { return index; }
glTF2Importer.cpp:_ZN10glTFCommonL9ReadValueINS_8NullableINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEEEEbRN9rapidjson12GenericValueINSA_4UTF8IcEENSA_19MemoryPoolAllocatorINSA_12CrtAllocatorEEEEERT_:
  364|  7.50k|inline static bool ReadValue(Value &val, T &out) {
  365|  7.50k|    return ReadHelper<T>::Read(val, out);
  366|  7.50k|}
_ZN10glTFCommon3RefIN5glTF25SceneEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|  1.90k|            vector(&vec),
  265|  1.90k|            index(idx) {}
_ZN10glTFCommon3RefIN5glTF24NodeEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|  14.1k|            vector(&vec),
  265|  14.1k|            index(idx) {}
_ZN10glTFCommon3RefIN5glTF26CameraEEC2Ev:
  261|  11.5k|            vector(nullptr),
  262|  11.5k|            index(0) {}
_ZN10glTFCommon3RefIN5glTF25LightEEC2Ev:
  261|  11.5k|            vector(nullptr),
  262|  11.5k|            index(0) {}
_ZN10glTFCommon3RefIN5glTF24SkinEEC2Ev:
  261|  11.5k|            vector(nullptr),
  262|  11.5k|            index(0) {}
_ZN10glTFCommon3RefIN5glTF24NodeEEC2Ev:
  261|  11.5k|            vector(nullptr),
  262|  11.5k|            index(0) {}
glTF2Importer.cpp:_ZN10glTFCommonL9ReadValueINS_8NullableIA16_fEEEEbRN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEERT_:
  364|  9.12k|inline static bool ReadValue(Value &val, T &out) {
  365|  9.12k|    return ReadHelper<T>::Read(val, out);
  366|  9.12k|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberINS_8NullableIA3_fEEEEbRN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEEPKcRT_:
  369|  4.27k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  4.27k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 4.27k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  4.27k|    Value::MemberIterator it = obj.FindMember(id);
  374|  4.27k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 0, False: 4.27k]
  ------------------
  375|      0|        return ReadHelper<T>::Read(it->value, out);
  376|      0|    }
  377|  4.27k|    return false;
  378|  4.27k|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberINS_8NullableIA4_fEEEEbRN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEEPKcRT_:
  369|  2.13k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  2.13k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 2.13k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  2.13k|    Value::MemberIterator it = obj.FindMember(id);
  374|  2.13k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 1, False: 2.13k]
  ------------------
  375|      1|        return ReadHelper<T>::Read(it->value, out);
  376|      1|    }
  377|  2.13k|    return false;
  378|  2.13k|}
_ZN10glTFCommon3RefIN5glTF24MeshEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|  1.78k|            vector(&vec),
  265|  1.78k|            index(idx) {}
_ZN10glTFCommon3RefIN5glTF28AccessorEEC2Ev:
  261|  8.18k|            vector(nullptr),
  262|  8.18k|            index(0) {}
_ZN10glTFCommon3RefIN5glTF28MaterialEEC2Ev:
  261|  1.94k|            vector(nullptr),
  262|  1.94k|            index(0) {}
glTF2Importer.cpp:_ZN10glTFCommonL15MemberOrDefaultIN5glTF213PrimitiveModeEEET_RN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEEPKcS3_:
  381|  1.94k|inline static T MemberOrDefault(Value &obj, const char *id, T defaultValue) {
  382|  1.94k|    T out;
  383|  1.94k|    return ReadMember(obj, id, out) ? out : defaultValue;
  ------------------
  |  Branch (383:12): [True: 1.78k, False: 161]
  ------------------
  384|  1.94k|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIN5glTF213PrimitiveModeEEEbRN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEEPKcRT_:
  369|  1.94k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  1.94k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 1, False: 1.94k]
  ------------------
  371|      1|        return false;
  372|      1|    }
  373|  1.94k|    Value::MemberIterator it = obj.FindMember(id);
  374|  1.94k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 1.78k, False: 158]
  ------------------
  375|  1.78k|        return ReadHelper<T>::Read(it->value, out);
  376|  1.78k|    }
  377|    158|    return false;
  378|  1.94k|}
_ZN10glTFCommon3RefIN5glTF28AccessorEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|  7.23k|            vector(&vec),
  265|  7.23k|            index(idx) {}
_ZN10glTFCommon3RefIN5glTF210BufferViewEEC2Ev:
  261|  7.14k|            vector(nullptr),
  262|  7.14k|            index(0) {}
_ZN10glTFCommon3RefIN5glTF210BufferViewEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|  6.93k|            vector(&vec),
  265|  6.93k|            index(idx) {}
glTF2Importer.cpp:_ZN10glTFCommonL15MemberOrDefaultIjEET_RN9rapidjson12GenericValueINS2_4UTF8IcEENS2_19MemoryPoolAllocatorINS2_12CrtAllocatorEEEEEPKcS1_:
  381|  6.68k|inline static T MemberOrDefault(Value &obj, const char *id, T defaultValue) {
  382|  6.68k|    T out;
  383|  6.68k|    return ReadMember(obj, id, out) ? out : defaultValue;
  ------------------
  |  Branch (383:12): [True: 1.63k, False: 5.04k]
  ------------------
  384|  6.68k|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIjEEbRN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEEPKcRT_:
  369|  6.68k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  6.68k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 6.68k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  6.68k|    Value::MemberIterator it = obj.FindMember(id);
  374|  6.68k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 1.63k, False: 5.04k]
  ------------------
  375|  1.63k|        return ReadHelper<T>::Read(it->value, out);
  376|  1.63k|    }
  377|  5.04k|    return false;
  378|  6.68k|}
glTF2Importer.cpp:_ZN10glTFCommonL15MemberOrDefaultImEET_RN9rapidjson12GenericValueINS2_4UTF8IcEENS2_19MemoryPoolAllocatorINS2_12CrtAllocatorEEEEEPKcS1_:
  381|  20.4k|inline static T MemberOrDefault(Value &obj, const char *id, T defaultValue) {
  382|  20.4k|    T out;
  383|  20.4k|    return ReadMember(obj, id, out) ? out : defaultValue;
  ------------------
  |  Branch (383:12): [True: 18.8k, False: 1.54k]
  ------------------
  384|  20.4k|}
glTF2Importer.cpp:_ZN10glTFCommonL15MemberOrDefaultIN5glTF213ComponentTypeEEET_RN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEEPKcS3_:
  381|  7.03k|inline static T MemberOrDefault(Value &obj, const char *id, T defaultValue) {
  382|  7.03k|    T out;
  383|  7.03k|    return ReadMember(obj, id, out) ? out : defaultValue;
  ------------------
  |  Branch (383:12): [True: 5.33k, False: 1.70k]
  ------------------
  384|  7.03k|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIN5glTF213ComponentTypeEEEbRN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEEPKcRT_:
  369|  7.03k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  7.03k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 7.03k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  7.03k|    Value::MemberIterator it = obj.FindMember(id);
  374|  7.03k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 5.34k, False: 1.69k]
  ------------------
  375|  5.34k|        return ReadHelper<T>::Read(it->value, out);
  376|  5.34k|    }
  377|  1.69k|    return false;
  378|  7.03k|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIPKcEEbRN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEES2_RT_:
  369|  7.02k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  7.02k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 7.02k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  7.02k|    Value::MemberIterator it = obj.FindMember(id);
  374|  7.02k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 6.80k, False: 220]
  ------------------
  375|  6.80k|        return ReadHelper<T>::Read(it->value, out);
  376|  6.80k|    }
  377|    220|    return false;
  378|  7.02k|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberImEEbRN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEEPKcRT_:
  369|  20.4k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  20.4k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 20.4k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  20.4k|    Value::MemberIterator it = obj.FindMember(id);
  374|  20.4k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 18.8k, False: 1.53k]
  ------------------
  375|  18.8k|        return ReadHelper<T>::Read(it->value, out);
  376|  18.8k|    }
  377|  1.53k|    return false;
  378|  20.4k|}
_ZN10glTFCommon3RefIN5glTF28MaterialEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|  1.52k|            vector(&vec),
  265|  1.52k|            index(idx) {}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIA4_fEEbRN9rapidjson12GenericValueINS2_4UTF8IcEENS2_19MemoryPoolAllocatorINS2_12CrtAllocatorEEEEEPKcRT_:
  369|  1.08k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  1.08k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 1.08k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  1.08k|    Value::MemberIterator it = obj.FindMember(id);
  374|  1.08k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 926, False: 158]
  ------------------
  375|    926|        return ReadHelper<T>::Read(it->value, out);
  376|    926|    }
  377|    158|    return false;
  378|  1.08k|}
_ZN10glTFCommon3RefIN5glTF27TextureEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|     64|            vector(&vec),
  265|     64|            index(idx) {}
_ZN10glTFCommon3RefIN5glTF27SamplerEEC2Ev:
  261|     74|            vector(nullptr),
  262|     74|            index(0) {}
_ZN10glTFCommon3RefIN5glTF25ImageEEC2Ev:
  261|     74|            vector(nullptr),
  262|     74|            index(0) {}
_ZN10glTFCommon3RefIN5glTF25ImageEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|     55|            vector(&vec),
  265|     55|            index(idx) {}
_ZN10glTFCommon3RefIN5glTF27SamplerEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|     59|            vector(&vec),
  265|     59|            index(idx) {}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIN5glTF216SamplerMagFilterEEEbRN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEEPKcRT_:
  369|     59|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|     59|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 59]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|     59|    Value::MemberIterator it = obj.FindMember(id);
  374|     59|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 5, False: 54]
  ------------------
  375|      5|        return ReadHelper<T>::Read(it->value, out);
  376|      5|    }
  377|     54|    return false;
  378|     59|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIN5glTF216SamplerMinFilterEEEbRN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEEPKcRT_:
  369|     59|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|     59|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 59]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|     59|    Value::MemberIterator it = obj.FindMember(id);
  374|     59|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 55, False: 4]
  ------------------
  375|     55|        return ReadHelper<T>::Read(it->value, out);
  376|     55|    }
  377|      4|    return false;
  378|     59|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIN5glTF211SamplerWrapEEEbRN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEEPKcRT_:
  369|    118|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|    118|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 118]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|    118|    Value::MemberIterator it = obj.FindMember(id);
  374|    118|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 109, False: 9]
  ------------------
  375|    109|        return ReadHelper<T>::Read(it->value, out);
  376|    109|    }
  377|      9|    return false;
  378|    118|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIfEEbRN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEEPKcRT_:
  369|  3.67k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  3.67k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 3.67k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  3.67k|    Value::MemberIterator it = obj.FindMember(id);
  374|  3.67k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 1.29k, False: 2.37k]
  ------------------
  375|  1.29k|        return ReadHelper<T>::Read(it->value, out);
  376|  1.29k|    }
  377|  2.37k|    return false;
  378|  3.67k|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIA3_fEEbRN9rapidjson12GenericValueINS2_4UTF8IcEENS2_19MemoryPoolAllocatorINS2_12CrtAllocatorEEEEEPKcRT_:
  369|  1.52k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  1.52k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 1.52k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  1.52k|    Value::MemberIterator it = obj.FindMember(id);
  374|  1.52k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 1.01k, False: 515]
  ------------------
  375|  1.01k|        return ReadHelper<T>::Read(it->value, out);
  376|  1.01k|    }
  377|    515|    return false;
  378|  1.52k|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIbEEbRN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEEPKcRT_:
  369|  1.52k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  1.52k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 1.52k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  1.52k|    Value::MemberIterator it = obj.FindMember(id);
  374|  1.52k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 929, False: 599]
  ------------------
  375|    929|        return ReadHelper<T>::Read(it->value, out);
  376|    929|    }
  377|    599|    return false;
  378|  1.52k|}
_ZN10glTFCommon3RefIN5glTF24SkinEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|    657|            vector(&vec),
  265|    657|            index(idx) {}
_ZN10glTFCommon3RefIN5glTF24NodeEEptEv:
  271|  4.39k|    T *operator->() { return (*vector)[index]; }
_ZN10glTFCommon3RefIN5glTF28AccessorEEptEv:
  271|  12.1k|    T *operator->() { return (*vector)[index]; }
_ZNK10glTFCommon3RefIN5glTF28MaterialEEcvbEv:
  269|  1.42k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 1.15k, False: 276]
  |  Branch (269:57): [True: 1.15k, False: 0]
  ------------------
_ZNK10glTFCommon3RefIN5glTF28AccessorEEcvbEv:
  269|  6.60k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 5.92k, False: 679]
  |  Branch (269:57): [True: 5.92k, False: 0]
  ------------------
_ZN10glTFCommon3RefIN5glTF24MeshEEptEv:
  271|    274|    T *operator->() { return (*vector)[index]; }
_ZNK10glTFCommon3RefIN5glTF24SkinEEcvbEv:
  269|  1.56k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 289, False: 1.27k]
  |  Branch (269:57): [True: 288, False: 1]
  ------------------
_ZN10glTFCommon3RefIN5glTF24SkinEEptEv:
  271|  2.70k|    T *operator->() { return (*vector)[index]; }
_ZNK10glTFCommon3RefIN5glTF25SceneEEcvbEv:
  269|  5.24k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 4.99k, False: 254]
  |  Branch (269:57): [True: 4.99k, False: 0]
  ------------------
_ZNK10glTFCommon3RefIN5glTF28MaterialEE8GetIndexEv:
  267|  1.15k|    inline unsigned int GetIndex() const { return index; }
_ZN10glTFCommon3RefIN5glTF24NodeEEdeEv:
  273|  10.4k|    T &operator*() { return *((*vector)[index]); }
_ZNK10glTFCommon3RefIN5glTF24MeshEE8GetIndexEv:
  267|  1.56k|    inline unsigned int GetIndex() const { return index; }

_ZN6Assimp12BaseImporterC2Ev:
   92|   167k|        : m_progress() {
   93|       |    // empty
   94|   167k|}
_ZN6Assimp12BaseImporter19UpdateImporterScaleEPNS_8ImporterE:
   96|  1.62k|void BaseImporter::UpdateImporterScale(Importer *pImp) {
   97|  1.62k|    ai_assert(pImp != nullptr);
   98|  1.62k|    ai_assert(importerScale != 0.0);
   99|  1.62k|    ai_assert(fileScale != 0.0);
  100|       |
  101|  1.62k|    double activeScale = importerScale * fileScale;
  102|       |
  103|       |    // Set active scaling
  104|  1.62k|    pImp->SetPropertyFloat(AI_CONFIG_APP_SCALE_KEY, static_cast<float>(activeScale));
  105|       |
  106|       |    ASSIMP_LOG_DEBUG("UpdateImporterScale scale set: ", activeScale);
  107|  1.62k|}
_ZN6Assimp12BaseImporter8ReadFileEPNS_8ImporterERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPNS_8IOSystemE:
  111|  2.47k|aiScene *BaseImporter::ReadFile(Importer *pImp, const std::string &pFile, IOSystem *pIOHandler) {
  112|       |
  113|  2.47k|    m_progress = pImp->GetProgressHandler();
  114|  2.47k|    if (nullptr == m_progress) {
  ------------------
  |  Branch (114:9): [True: 0, False: 2.47k]
  ------------------
  115|      0|        return nullptr;
  116|      0|    }
  117|       |
  118|  2.47k|    ai_assert(m_progress);
  119|       |
  120|       |    // Gather configuration properties for this run
  121|  2.47k|    SetupProperties(pImp);
  122|       |
  123|       |    // Construct a file system filter to improve our success ratio at reading external files
  124|  2.47k|    FileSystemFilter filter(pFile, pIOHandler);
  125|       |
  126|       |    // create a scene object to hold the data
  127|  2.47k|    std::unique_ptr<aiScene> sc(new aiScene());
  128|       |
  129|       |    // dispatch importing
  130|  2.47k|    try {
  131|  2.47k|        InternReadFile(pFile, sc.get(), &filter);
  132|       |
  133|       |        // Calculate import scale hook - required because pImp not available anywhere else
  134|       |        // passes scale into ScaleProcess
  135|  2.47k|        UpdateImporterScale(pImp);
  136|       |
  137|  2.47k|    } catch( const std::exception &err ) {
  138|       |        // extract error description
  139|    855|        m_ErrorText = err.what();
  140|    855|        ASSIMP_LOG_ERROR(err.what());
  141|    855|        m_Exception = std::current_exception();
  142|    855|        return nullptr;
  143|    855|    }
  144|       |
  145|       |    // return what we gathered from the import.
  146|  1.62k|    return sc.release();
  147|  2.47k|}
_ZN6Assimp12BaseImporter15SetupPropertiesEPKNS_8ImporterE:
  150|     89|void BaseImporter::SetupProperties(const Importer *) {
  151|       |    // the default implementation does nothing
  152|     89|}
_ZN6Assimp12BaseImporter16GetExtensionListERNSt3__13setINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_4lessIS8_EENS6_IS8_EEEE:
  155|  6.97k|void BaseImporter::GetExtensionList(std::set<std::string> &extensions) {
  156|  6.97k|    const aiImporterDesc *desc = GetInfo();
  157|  6.97k|    ai_assert(desc != nullptr);
  158|       |
  159|  6.97k|    const char *ext = desc->mFileExtensions;
  160|  6.97k|    ai_assert(ext != nullptr);
  161|       |
  162|  6.97k|    const char *last = ext;
  163|  76.7k|    do {
  164|  76.7k|        if (!*ext || *ext == ' ') {
  ------------------
  |  Branch (164:13): [True: 6.97k, False: 69.7k]
  |  Branch (164:22): [True: 10.4k, False: 59.2k]
  ------------------
  165|  17.4k|            extensions.insert(std::string(last, ext - last));
  166|  17.4k|            ai_assert(ext - last > 0);
  167|  17.4k|            last = ext;
  168|  27.9k|            while (*last == ' ') {
  ------------------
  |  Branch (168:20): [True: 10.4k, False: 17.4k]
  ------------------
  169|  10.4k|                ++last;
  170|  10.4k|            }
  171|  17.4k|        }
  172|  76.7k|    } while (*ext++);
  ------------------
  |  Branch (172:14): [True: 69.7k, False: 6.97k]
  ------------------
  173|  6.97k|}
_ZN6Assimp12BaseImporter12HasExtensionERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKNS1_3setIS7_NS1_4lessIS7_EENS5_IS7_EEEE:
  265|  6.97k|/*static*/ bool BaseImporter::HasExtension(const std::string &pFile, const std::set<std::string> &extensions) {
  266|  6.97k|    const std::string file = StripVersionHash(pFile);
  267|       |    // CAUTION: Do not just search for the extension!
  268|       |    // GetExtension() returns the part after the *last* dot, but some extensions
  269|       |    // have dots inside them, e.g. ogre.mesh.xml. Compare the entire end of the
  270|       |    // string.
  271|  6.97k|    for (const std::string& ext : extensions) {
  ------------------
  |  Branch (271:33): [True: 6.97k, False: 0]
  ------------------
  272|       |        // Yay for C++<20 not having std::string::ends_with()
  273|  6.97k|        const std::string dotExt = "." + ext;
  274|  6.97k|        if (dotExt.length() > file.length()) continue;
  ------------------
  |  Branch (274:13): [True: 0, False: 6.97k]
  ------------------
  275|       |        // Possible optimization: Fetch the lowercase filename!
  276|  6.97k|        if (0 == ASSIMP_stricmp(file.c_str() + file.length() - dotExt.length(), dotExt.c_str())) {
  ------------------
  |  Branch (276:13): [True: 6.97k, False: 0]
  ------------------
  277|  6.97k|            return true;
  278|  6.97k|        }
  279|  6.97k|    }
  280|      0|    return false;
  281|  6.97k|}
_ZN6Assimp12BaseImporter12GetExtensionERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  285|  4.40k|std::string BaseImporter::GetExtension(const std::string &pFile) {
  286|  4.40k|    const std::string file = StripVersionHash(pFile);
  287|  4.40k|    std::string::size_type pos = file.find_last_of('.');
  288|       |
  289|       |    // no file extension at all
  290|  4.40k|    if (pos == std::string::npos) {
  ------------------
  |  Branch (290:9): [True: 0, False: 4.40k]
  ------------------
  291|      0|        return std::string();
  292|      0|    }
  293|       |
  294|       |    // thanks to Andy Maloney for the hint
  295|  4.40k|    std::string ret = file.substr(pos + 1);
  296|  4.40k|    ret = ai_tolower(ret);
  297|       |
  298|  4.40k|    return ret;
  299|  4.40k|}
_ZN6Assimp12BaseImporter15CheckMagicTokenEPNS_8IOSystemERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPKvmjj:
  305|  11.3k|        const void *_magic, std::size_t num, unsigned int offset, unsigned int size) {
  306|  11.3k|    ai_assert(size <= 16);
  307|  11.3k|    ai_assert(_magic);
  308|       |
  309|  11.3k|    if (!pIOHandler) {
  ------------------
  |  Branch (309:9): [True: 0, False: 11.3k]
  ------------------
  310|      0|        return false;
  311|      0|    }
  312|  11.3k|    const char *magic = reinterpret_cast<const char *>(_magic);
  313|  11.3k|    std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile));
  314|  11.3k|    if (pStream) {
  ------------------
  |  Branch (314:9): [True: 11.3k, False: 0]
  ------------------
  315|       |
  316|       |        // skip to offset
  317|  11.3k|        pStream->Seek(offset, aiOrigin_SET);
  318|       |
  319|       |        // read 'size' characters from the file
  320|  11.3k|        union {
  321|  11.3k|            char data[16];
  322|  11.3k|            uint16_t data_u16[8];
  323|  11.3k|            uint32_t data_u32[4];
  324|  11.3k|        };
  325|  11.3k|        if (size != pStream->Read(data, 1, size)) {
  ------------------
  |  Branch (325:13): [True: 0, False: 11.3k]
  ------------------
  326|      0|            return false;
  327|      0|        }
  328|       |
  329|  15.8k|        for (unsigned int i = 0; i < num; ++i) {
  ------------------
  |  Branch (329:34): [True: 11.3k, False: 4.45k]
  ------------------
  330|       |            // also check against big endian versions of tokens with size 2,4
  331|       |            // that's just for convenience, the chance that we cause conflicts
  332|       |            // is quite low and it can save some lines and prevent nasty bugs
  333|  11.3k|            if (2 == size) {
  ------------------
  |  Branch (333:17): [True: 0, False: 11.3k]
  ------------------
  334|      0|                uint16_t magic_u16;
  335|      0|                memcpy(&magic_u16, magic, 2);
  336|      0|                if (data_u16[0] == magic_u16 || data_u16[0] == ByteSwap::Swapped(magic_u16)) {
  ------------------
  |  Branch (336:21): [True: 0, False: 0]
  |  Branch (336:49): [True: 0, False: 0]
  ------------------
  337|      0|                    return true;
  338|      0|                }
  339|  11.3k|            } else if (4 == size) {
  ------------------
  |  Branch (339:24): [True: 11.3k, False: 0]
  ------------------
  340|  11.3k|                uint32_t magic_u32;
  341|  11.3k|                memcpy(&magic_u32, magic, 4);
  342|  11.3k|                if (data_u32[0] == magic_u32 || data_u32[0] == ByteSwap::Swapped(magic_u32)) {
  ------------------
  |  Branch (342:21): [True: 6.93k, False: 4.45k]
  |  Branch (342:49): [True: 0, False: 4.45k]
  ------------------
  343|  6.93k|                    return true;
  344|  6.93k|                }
  345|  11.3k|            } else {
  346|       |                // any length ... just compare
  347|      0|                if (!memcmp(magic, data, size)) {
  ------------------
  |  Branch (347:21): [True: 0, False: 0]
  ------------------
  348|      0|                    return true;
  349|      0|                }
  350|      0|            }
  351|  4.45k|            magic += size;
  352|  4.45k|        }
  353|  11.3k|    }
  354|  4.45k|    return false;
  355|  11.3k|}
BaseImporter.cpp:_ZN12_GLOBAL__N_116StripVersionHashERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
   75|  11.3k|std::string StripVersionHash(const std::string &filename) {
   76|  11.3k|    const std::string::size_type pos = filename.find_last_of('#');
   77|       |    // Only strip if the hash is behind a possible file extension and the part
   78|       |    // behind the hash is a version string.
   79|  11.3k|    if (pos != std::string::npos && pos > filename.find_last_of('.') &&
  ------------------
  |  Branch (79:9): [True: 0, False: 11.3k]
  |  Branch (79:9): [True: 0, False: 11.3k]
  |  Branch (79:37): [True: 0, False: 0]
  ------------------
   80|      0|        IsGcsVersion(filename.substr(pos + 1))) {
  ------------------
  |  Branch (80:9): [True: 0, False: 0]
  ------------------
   81|      0|        return filename.substr(0, pos);
   82|      0|    }
   83|  11.3k|    return filename;
   84|  11.3k|}

_ZN6Assimp11BaseProcessC2Ev:
   56|   116k|          progress() {
   57|       |    // empty
   58|   116k|}
_ZN6Assimp11BaseProcess14ExecuteOnSceneEPNS_8ImporterE:
   61|  23.4k|void BaseProcess::ExecuteOnScene(Importer *pImp) {
   62|  23.4k|    ai_assert( nullptr != pImp );
   63|  23.4k|    if (pImp == nullptr) {
  ------------------
  |  Branch (63:9): [True: 0, False: 23.4k]
  ------------------
   64|      0|        return;
   65|      0|    }
   66|       |
   67|  23.4k|    ai_assert(nullptr != pImp->Pimpl()->mScene);
   68|  23.4k|    if (pImp->Pimpl()->mScene == nullptr) {
  ------------------
  |  Branch (68:9): [True: 0, False: 23.4k]
  ------------------
   69|      0|        return;
   70|      0|    }
   71|       |
   72|  23.4k|    progress = pImp->GetProgressHandler();
   73|  23.4k|    ai_assert(nullptr != progress);
   74|  23.4k|    if (progress == nullptr) {
  ------------------
  |  Branch (74:9): [True: 0, False: 23.4k]
  ------------------
   75|      0|        return;
   76|      0|    }
   77|       |
   78|  23.4k|    SetupProperties(pImp);
   79|       |
   80|       |    // catch exceptions thrown inside the PostProcess-Step
   81|  23.4k|    try {
   82|  23.4k|        Execute(pImp->Pimpl()->mScene);
   83|  23.4k|    } catch (const std::exception &err) {
   84|       |
   85|       |        // extract error description
   86|    192|        pImp->Pimpl()->mErrorString = err.what();
   87|    192|        ASSIMP_LOG_ERROR(pImp->Pimpl()->mErrorString);
   88|       |
   89|       |        // and kill the partially imported data
   90|    192|        delete pImp->Pimpl()->mScene;
   91|    192|        pImp->Pimpl()->mScene = nullptr;
   92|    192|    }
   93|  23.4k|}
_ZN6Assimp11BaseProcess15SetupPropertiesEPKNS_8ImporterE:
   96|  8.89k|void BaseProcess::SetupProperties(const Importer * /*pImp*/) {
   97|       |    // the default implementation does nothing
   98|  8.89k|}

_ZN6Assimp11BaseProcess13SetSharedDataEPNS_21SharedPostProcessInfoE:
  234|   115k|    inline void SetSharedData(SharedPostProcessInfo *sh) {
  235|   115k|        shared = sh;
  236|   115k|    }
_ZN6Assimp21SharedPostProcessInfoD2Ev:
   98|  3.48k|    ~SharedPostProcessInfo() {
   99|  3.48k|        Clean();
  100|  3.48k|    }
_ZN6Assimp11BaseProcessD2Ev:
  186|   116k|    virtual ~BaseProcess() = default;
_ZN6Assimp21SharedPostProcessInfo5CleanEv:
  103|  7.31k|    void Clean() {
  104|       |        // invoke the virtual destructor for all stored properties
  105|  7.31k|        for (PropertyMap::iterator it = pmap.begin(), end = pmap.end();
  106|  7.31k|                it != end; ++it) {
  ------------------
  |  Branch (106:17): [True: 0, False: 7.31k]
  ------------------
  107|      0|            delete (*it).second;
  108|      0|        }
  109|  7.31k|        pmap.clear();
  110|  7.31k|    }
_ZN6Assimp21SharedPostProcessInfo14RemovePropertyEPKc:
  148|  1.43k|    void RemoveProperty(const char *name) {
  149|  1.43k|        SetGenericPropertyPtr<Base>(pmap, name, nullptr );
  150|  1.43k|    }
_ZN6Assimp21SharedPostProcessInfo11AddPropertyEPKcPNS0_4BaseE:
  153|  1.43k|    void AddProperty(const char *name, Base *data) {
  154|  1.43k|        SetGenericPropertyPtr<Base>(pmap, name, data);
  155|  1.43k|    }
_ZNK6Assimp21SharedPostProcessInfo19GetPropertyInternalEPKc:
  157|    793|    Base *GetPropertyInternal(const char *name) const {
  158|    793|        return GetGenericProperty<Base *>(pmap, name, nullptr );
  159|    793|    }
_ZN6Assimp21SharedPostProcessInfo11AddPropertyINSt3__16vectorINS2_4pairINS_11SpatialSortEfEENS2_9allocatorIS6_EEEEEEvPKcPT_:
  114|  1.43k|    void AddProperty(const char *name, T *in) {
  115|  1.43k|        AddProperty(name, (Base *)new THeapData<T>(in));
  116|  1.43k|    }
_ZN6Assimp21SharedPostProcessInfo9THeapDataINSt3__16vectorINS2_4pairINS_11SpatialSortEfEENS2_9allocatorIS6_EEEEEC2EPS9_:
   73|  1.43k|                data(in) {}
_ZN6Assimp21SharedPostProcessInfo4BaseD2Ev:
   66|  1.43k|        virtual ~Base() = default;
_ZN6Assimp21SharedPostProcessInfo9THeapDataINSt3__16vectorINS2_4pairINS_11SpatialSortEfEENS2_9allocatorIS6_EEEEED2Ev:
   75|  1.43k|        ~THeapData() override {
   76|  1.43k|            delete data;
   77|  1.43k|        }
_ZNK6Assimp21SharedPostProcessInfo11GetPropertyINSt3__16vectorINS2_4pairINS_11SpatialSortEfEENS2_9allocatorIS6_EEEEEEbPKcRPT_:
  126|    793|    bool GetProperty(const char *name, T *&out) const {
  127|    793|        THeapData<T> *t = (THeapData<T> *)GetPropertyInternal(name);
  128|    793|        if (!t) {
  ------------------
  |  Branch (128:13): [True: 0, False: 793]
  ------------------
  129|      0|            out = nullptr;
  130|      0|            return false;
  131|      0|        }
  132|    793|        out = t->data;
  133|    793|        return true;
  134|    793|    }

_ZNK6Assimp15DefaultIOSystem14getOsSeparatorEv:
  152|  9.45k|char DefaultIOSystem::getOsSeparator() const {
  153|  9.45k|#ifndef _WIN32
  154|  9.45k|    return '/';
  155|       |#else
  156|       |    return '\\';
  157|       |#endif
  158|  9.45k|}

_ZN6Assimp6Logger5debugEPKc:
  166|  68.2k|void Logger::debug(const char *message) {
  167|       |
  168|       |    // SECURITY FIX: otherwise it's easy to produce overruns since
  169|       |    // sometimes importers will include data from the input file
  170|       |    // (i.e. node names) in their messages.
  171|  68.2k|    if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) {
  ------------------
  |  Branch (171:9): [True: 0, False: 68.2k]
  ------------------
  172|      0|        return OnDebug("<fixme: long message discarded>");
  173|      0|    }
  174|  68.2k|    return OnDebug(message);
  175|  68.2k|}
_ZN6Assimp6Logger4infoEPKc:
  188|   186k|void Logger::info(const char *message) {
  189|       |
  190|       |    // SECURITY FIX: see above
  191|   186k|    if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) {
  ------------------
  |  Branch (191:9): [True: 0, False: 186k]
  ------------------
  192|      0|        return OnInfo("<fixme: long message discarded>");
  193|      0|    }
  194|   186k|    return OnInfo(message);
  195|   186k|}
_ZN6Assimp6Logger4warnEPKc:
  198|  3.39k|void Logger::warn(const char *message) {
  199|       |
  200|       |    // SECURITY FIX: see above
  201|  3.39k|    if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) {
  ------------------
  |  Branch (201:9): [True: 0, False: 3.39k]
  ------------------
  202|      0|        return OnWarn("<fixme: long message discarded>");
  203|      0|    }
  204|  3.39k|    return OnWarn(message);
  205|  3.39k|}
_ZN6Assimp6Logger5errorEPKc:
  208|  5.02k|void Logger::error(const char *message) {
  209|       |    // SECURITY FIX: see above
  210|  5.02k|    if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) {
  ------------------
  |  Branch (210:9): [True: 3, False: 5.02k]
  ------------------
  211|      3|        return OnError("<fixme: long message discarded>");
  212|      3|    }
  213|  5.02k|    return OnError(message);
  214|  5.02k|}
_ZN6Assimp13DefaultLogger12isNullLoggerEv:
  232|  9.70k|bool DefaultLogger::isNullLogger() {
  233|  9.70k|    return m_pLogger == &s_pNullLogger;
  234|  9.70k|}
_ZN6Assimp13DefaultLogger3getEv:
  237|   262k|Logger *DefaultLogger::get() {
  238|   262k|    return m_pLogger;
  239|   262k|}

_ZN6Assimp22DefaultProgressHandler6UpdateEf:
   59|  54.6k|    bool Update(float) override {
   60|  54.6k|        return false;
   61|  54.6k|    }

_ZN15DeadlyErrorBaseC2EN6Assimp9Formatter15basic_formatterIcNSt3__111char_traitsIcEENS3_9allocatorIcEEEE:
   52|  6.92k|        runtime_error(std::string(f)){}

_ZN6Assimp16FileSystemFilterC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEPNS_8IOSystemE:
   68|  2.47k|    : mWrapped  (old)
   69|  2.47k|    , mSrc_file(file)
   70|  2.47k|    , mSep(mWrapped->getOsSeparator()) {
   71|  2.47k|        ai_assert(nullptr != mWrapped);
   72|       |
   73|       |        // Determine base directory
   74|  2.47k|        mBase = mSrc_file;
   75|  2.47k|        std::string::size_type ss2;
   76|  2.47k|        if (std::string::npos != (ss2 = mBase.find_last_of("\\/")))  {
  ------------------
  |  Branch (76:13): [True: 0, False: 2.47k]
  ------------------
   77|      0|            mBase.erase(ss2,mBase.length()-ss2);
   78|  2.47k|        } else {
   79|  2.47k|            mBase = std::string();
   80|  2.47k|        }
   81|       |
   82|       |        // make sure the directory is terminated properly
   83|  2.47k|        char s;
   84|       |
   85|  2.47k|        if ( mBase.empty() ) {
  ------------------
  |  Branch (85:14): [True: 2.47k, False: 0]
  ------------------
   86|  2.47k|            mBase = ".";
   87|  2.47k|            mBase += getOsSeparator();
   88|  2.47k|        } else if ((s = *(mBase.end()-1)) != '\\' && s != '/') {
  ------------------
  |  Branch (88:20): [True: 0, False: 0]
  |  Branch (88:20): [True: 0, False: 0]
  |  Branch (88:54): [True: 0, False: 0]
  ------------------
   89|      0|            mBase += getOsSeparator();
   90|      0|        }
   91|       |
   92|  2.47k|        DefaultLogger::get()->info("Import root directory is \'", mBase, "\'");
   93|  2.47k|    }
_ZNK6Assimp16FileSystemFilter14getOsSeparatorEv:
  116|  2.47k|    char getOsSeparator() const {
  117|  2.47k|        return mSep;
  118|  2.47k|    }
_ZN6Assimp16FileSystemFilter4OpenEPKcS2_:
  122|  4.95k|    IOStream* Open( const char* pFile, const char* pMode = "rb") {
  123|  4.95k|        ai_assert( nullptr != mWrapped );
  124|  4.95k|        if ( nullptr == pFile || nullptr == pMode ) {
  ------------------
  |  Branch (124:14): [True: 0, False: 4.95k]
  |  Branch (124:34): [True: 0, False: 4.95k]
  ------------------
  125|      0|            return nullptr;
  126|      0|        }
  127|       |
  128|  4.95k|        ai_assert( nullptr != pFile );
  129|  4.95k|        ai_assert( nullptr != pMode );
  130|       |
  131|       |        // First try the unchanged path
  132|  4.95k|        IOStream* s = mWrapped->Open(pFile,pMode);
  133|       |
  134|  4.95k|        if (nullptr == s) {
  ------------------
  |  Branch (134:13): [True: 0, False: 4.95k]
  ------------------
  135|      0|            std::string tmp = pFile;
  136|       |
  137|       |            // Try to convert between absolute and relative paths
  138|      0|            BuildPath(tmp);
  139|      0|            s = mWrapped->Open(tmp,pMode);
  140|       |
  141|      0|            if (nullptr == s) {
  ------------------
  |  Branch (141:17): [True: 0, False: 0]
  ------------------
  142|       |                // Finally, look for typical issues with paths
  143|       |                // and try to correct them. This is our last
  144|       |                // resort.
  145|      0|                tmp = pFile;
  146|      0|                Cleanup(tmp);
  147|      0|                BuildPath(tmp);
  148|      0|                s = mWrapped->Open(tmp,pMode);
  149|      0|            }
  150|      0|        }
  151|       |
  152|  4.95k|        return s;
  153|  4.95k|    }
_ZN6Assimp16FileSystemFilterD2Ev:
   96|  2.47k|    ~FileSystemFilter() = default;

_ZN6Assimp6Intern22AllocateFromAssimpHeapnwEm:
  114|  35.7k|void* AllocateFromAssimpHeap::operator new ( size_t num_bytes)  {
  115|  35.7k|    return ::operator new(num_bytes);
  116|  35.7k|}
_ZN6Assimp6Intern22AllocateFromAssimpHeapdlEPv:
  127|  35.7k|void AllocateFromAssimpHeap::operator delete ( void* data)  {
  128|  35.7k|    return ::operator delete(data);
  129|  35.7k|}
_ZN6Assimp8ImporterC2Ev:
  150|  3.48k| : pimpl( new ImporterPimpl ) {
  151|  3.48k|    pimpl->mScene = nullptr;
  152|  3.48k|    pimpl->mErrorString = std::string();
  153|       |
  154|       |    // Allocate a default IO handler
  155|  3.48k|    pimpl->mIOHandler = new DefaultIOSystem;
  156|  3.48k|    pimpl->mIsDefaultHandler = true;
  157|  3.48k|    pimpl->bExtraVerbose     = false; // disable extra verbose mode by default
  158|       |
  159|  3.48k|    pimpl->mProgressHandler = new DefaultProgressHandler();
  160|  3.48k|    pimpl->mIsDefaultProgressHandler = true;
  161|       |
  162|  3.48k|    GetImporterInstanceList(pimpl->mImporter);
  163|  3.48k|    GetPostProcessingStepInstanceList(pimpl->mPostProcessingSteps);
  164|       |
  165|       |    // Allocate a SharedPostProcessInfo object and store pointers to it in all post-process steps in the list.
  166|  3.48k|    pimpl->mPPShared = new SharedPostProcessInfo();
  167|  3.48k|    for (std::vector<BaseProcess*>::iterator it =  pimpl->mPostProcessingSteps.begin();
  168|   118k|        it != pimpl->mPostProcessingSteps.end();
  ------------------
  |  Branch (168:9): [True: 115k, False: 3.48k]
  ------------------
  169|   115k|        ++it)   {
  170|       |
  171|   115k|        (*it)->SetSharedData(pimpl->mPPShared);
  172|   115k|    }
  173|  3.48k|}
_ZN6Assimp8ImporterD2Ev:
  177|  3.48k|Importer::~Importer() {
  178|       |    // Delete all import plugins
  179|  3.48k|	DeleteImporterInstanceList(pimpl->mImporter);
  180|       |
  181|       |    // Delete all post-processing plug-ins
  182|   118k|    for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); ++a ) {
  ------------------
  |  Branch (182:30): [True: 115k, False: 3.48k]
  ------------------
  183|   115k|        delete pimpl->mPostProcessingSteps[a];
  184|   115k|    }
  185|       |
  186|       |    // Delete the assigned IO and progress handler
  187|  3.48k|    delete pimpl->mIOHandler;
  188|  3.48k|    delete pimpl->mProgressHandler;
  189|       |
  190|       |    // Kill imported scene. Destructor's should do that recursively
  191|  3.48k|    delete pimpl->mScene;
  192|       |
  193|       |    // Delete shared post-processing data
  194|  3.48k|    delete pimpl->mPPShared;
  195|       |
  196|       |    // and finally the pimpl itself
  197|  3.48k|    delete pimpl;
  198|  3.48k|}
_ZN6Assimp8Importer16UnregisterLoaderEPNS_12BaseImporterE:
  251|   160k|aiReturn Importer::UnregisterLoader(BaseImporter* pImp) {
  252|   160k|    if(!pImp) {
  ------------------
  |  Branch (252:8): [True: 0, False: 160k]
  ------------------
  253|       |        // unregistering a nullptr importer is no problem for us ... really!
  254|      0|        return AI_SUCCESS;
  255|      0|    }
  256|       |
  257|   160k|    ASSIMP_BEGIN_EXCEPTION_REGION();
  258|   160k|    std::vector<BaseImporter*>::iterator it = std::find(pimpl->mImporter.begin(),
  259|   160k|        pimpl->mImporter.end(),pImp);
  260|       |
  261|   160k|    if (it != pimpl->mImporter.end())   {
  ------------------
  |  Branch (261:9): [True: 160k, False: 0]
  ------------------
  262|   160k|        pimpl->mImporter.erase(it);
  263|   160k|        ASSIMP_LOG_INFO("Unregistering custom importer: ");
  264|   160k|        return AI_SUCCESS;
  265|   160k|    }
  266|   160k|    ASSIMP_LOG_WARN("Unable to remove custom importer: I can't find you ...");
  267|      0|    ASSIMP_END_EXCEPTION_REGION(aiReturn);
  268|       |
  269|       |    return AI_FAILURE;
  270|   160k|}
_ZN6Assimp8Importer12SetIOHandlerEPNS_8IOSystemE:
  297|  6.97k|void Importer::SetIOHandler( IOSystem* pIOHandler) {
  298|  6.97k|    ai_assert(nullptr != pimpl);
  299|       |
  300|  6.97k|    ASSIMP_BEGIN_EXCEPTION_REGION();
  301|       |    // If the new handler is zero, allocate a default IO implementation.
  302|  6.97k|    if (!pIOHandler) {
  ------------------
  |  Branch (302:9): [True: 0, False: 6.97k]
  ------------------
  303|       |        // Release pointer in the possession of the caller
  304|      0|        pimpl->mIOHandler = new DefaultIOSystem();
  305|      0|        pimpl->mIsDefaultHandler = true;
  306|  6.97k|    } else if (pimpl->mIOHandler != pIOHandler) { // Otherwise register the custom handler
  ------------------
  |  Branch (306:16): [True: 6.97k, False: 0]
  ------------------
  307|  6.97k|        delete pimpl->mIOHandler;
  308|  6.97k|        pimpl->mIOHandler = pIOHandler;
  309|  6.97k|        pimpl->mIsDefaultHandler = false;
  310|  6.97k|    }
  311|  6.97k|    ASSIMP_END_EXCEPTION_REGION(void);
  312|  6.97k|}
_ZNK6Assimp8Importer18GetProgressHandlerEv:
  352|  25.9k|ProgressHandler* Importer::GetProgressHandler() const {
  353|  25.9k|    ai_assert(nullptr != pimpl);
  354|       |
  355|  25.9k|    return pimpl->mProgressHandler;
  356|  25.9k|}
_Z14_ValidateFlagsj:
  368|  1.48k|bool _ValidateFlags(unsigned int pFlags) {
  369|  1.48k|    if (pFlags & aiProcess_GenSmoothNormals && pFlags & aiProcess_GenNormals)   {
  ------------------
  |  Branch (369:9): [True: 1.48k, False: 0]
  |  Branch (369:48): [True: 0, False: 1.48k]
  ------------------
  370|      0|        ASSIMP_LOG_ERROR("#aiProcess_GenSmoothNormals and #aiProcess_GenNormals are incompatible");
  371|      0|        return false;
  372|      0|    }
  373|  1.48k|    if (pFlags & aiProcess_OptimizeGraph && pFlags & aiProcess_PreTransformVertices)    {
  ------------------
  |  Branch (373:9): [True: 0, False: 1.48k]
  |  Branch (373:45): [True: 0, False: 0]
  ------------------
  374|      0|        ASSIMP_LOG_ERROR("#aiProcess_OptimizeGraph and #aiProcess_PreTransformVertices are incompatible");
  375|      0|        return false;
  376|      0|    }
  377|  1.48k|    return true;
  378|  1.48k|}
_ZN6Assimp8Importer18ReadFileFromMemoryEPKvmjPKc:
  485|  3.48k|const aiScene* Importer::ReadFileFromMemory(const void* pBuffer, size_t pLength, unsigned int pFlags, const char* pHint ) {
  486|  3.48k|    ai_assert(nullptr != pimpl);
  487|       |
  488|  3.48k|    IOSystem* io = pimpl->mIOHandler;
  489|  3.48k|    try {
  490|  3.48k|        if (pHint == nullptr) {
  ------------------
  |  Branch (490:13): [True: 0, False: 3.48k]
  ------------------
  491|      0|            pHint = "";
  492|      0|        }
  493|  3.48k|        if (!pBuffer || !pLength || strlen(pHint) > MaxLenHint ) {
  ------------------
  |  Branch (493:13): [True: 0, False: 3.48k]
  |  Branch (493:25): [True: 0, False: 3.48k]
  |  Branch (493:37): [True: 0, False: 3.48k]
  ------------------
  494|      0|            pimpl->mErrorString = "Invalid parameters passed to ReadFileFromMemory()";
  495|      0|            return nullptr;
  496|      0|        }
  497|       |        // prevent deletion of the previous IOHandler
  498|  3.48k|        pimpl->mIOHandler = nullptr;
  499|       |
  500|  3.48k|        SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength,io));
  501|       |
  502|       |        // read the file and recover the previous IOSystem
  503|  3.48k|        static const size_t BufSize(Importer::MaxLenHint + 28);
  504|  3.48k|        char fbuff[BufSize];
  505|  3.48k|        ai_snprintf(fbuff, BufSize, "%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint);
  506|       |
  507|  3.48k|        ReadFile(fbuff,pFlags);
  508|  3.48k|        SetIOHandler(io);
  509|  3.48k|    } catch(const DeadlyImportError &e) {
  510|      0|        pimpl->mErrorString = e.what();
  511|      0|        pimpl->mException = std::current_exception();
  512|      0|        SetIOHandler(io);
  513|      0|        return ExceptionSwallower<const aiScene*>()();                                                                                                    \
  514|      0|    } catch(...) {
  515|      0|        pimpl->mErrorString = "Unknown exception";
  516|      0|        pimpl->mException = std::current_exception();
  517|      0|        SetIOHandler(io);
  518|      0|        return ExceptionSwallower<const aiScene*>()();                                                                                                    \
  519|      0|
  520|      0|    }
  521|       |
  522|  3.48k|    return pimpl->mScene;
  523|  3.48k|}
_Z15WriteLogOpeningRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE:
  526|  3.48k|void WriteLogOpening(const std::string& file) {
  527|       |
  528|  3.48k|    ASSIMP_LOG_INFO("Load ", file);
  529|       |
  530|       |    // print a full version dump. This is nice because we don't
  531|       |    // need to ask the authors of incoming bug reports for
  532|       |    // the library version they're using - a log dump is
  533|       |    // sufficient.
  534|  3.48k|    const unsigned int flags = aiGetCompileFlags();
  535|  3.48k|    std::stringstream stream;
  536|  3.48k|    stream << "Assimp " << aiGetVersionMajor() << "." << aiGetVersionMinor() << "." << aiGetVersionRevision() << " "
  537|       |#if defined(ASSIMP_BUILD_ARCHITECTURE)
  538|       |           << ASSIMP_BUILD_ARCHITECTURE
  539|       |#elif defined(_M_IX86) || defined(__x86_32__) || defined(__i386__)
  540|       |           << "x86"
  541|       |#elif defined(_M_X64) || defined(__x86_64__)
  542|       |           << "amd64"
  543|       |#elif defined(_M_IA64) || defined(__ia64__)
  544|       |           << "itanium"
  545|       |#elif defined(__ppc__) || defined(__powerpc__)
  546|       |           << "ppc32"
  547|       |#elif defined(__powerpc64__)
  548|       |           << "ppc64"
  549|       |#elif defined(__arm__)
  550|       |           << "arm"
  551|       |#else
  552|       |           << "<unknown architecture>"
  553|       |#endif
  554|  3.48k|           << " "
  555|       |#if defined(ASSIMP_BUILD_COMPILER)
  556|       |           << (ASSIMP_BUILD_COMPILER)
  557|       |#elif defined(_MSC_VER)
  558|       |           << "msvc"
  559|       |#elif defined(__GNUC__)
  560|       |           << "gcc"
  561|       |#elif defined(__clang__)
  562|       |           << "clang"
  563|       |#elif defined(__EMSCRIPTEN__)
  564|       |           << "emscripten"
  565|       |#elif defined(__MINGW32__)
  566|       |           << "MinGW-w64 32bit"
  567|       |#elif defined(__MINGW64__)
  568|       |           << "MinGW-w64 64bit"
  569|       |#else
  570|       |           << "<unknown compiler>"
  571|       |#endif
  572|       |
  573|  3.48k|#ifdef ASSIMP_BUILD_DEBUG
  574|  3.48k|           << " debug"
  575|  3.48k|#endif
  576|       |
  577|  3.48k|           << (flags & ASSIMP_CFLAGS_NOBOOST ? " noboost" : "")
  ------------------
  |  |  105|  3.48k|#define ASSIMP_CFLAGS_NOBOOST           0x8
  ------------------
  |  Branch (577:16): [True: 0, False: 3.48k]
  ------------------
  578|  3.48k|           << (flags & ASSIMP_CFLAGS_SHARED ? " shared" : "")
  ------------------
  |  |   98|  3.48k|#define ASSIMP_CFLAGS_SHARED  0x1
  ------------------
  |  Branch (578:16): [True: 0, False: 3.48k]
  ------------------
  579|  3.48k|           << (flags & ASSIMP_CFLAGS_SINGLETHREADED ? " singlethreaded" : "")
  ------------------
  |  |  107|  3.48k|#define ASSIMP_CFLAGS_SINGLETHREADED    0x10
  ------------------
  |  Branch (579:16): [True: 3.48k, False: 0]
  ------------------
  580|  3.48k|           << (flags & ASSIMP_CFLAGS_DOUBLE_SUPPORT ? " double : " : "single : ");
  ------------------
  |  |  109|  3.48k|#define ASSIMP_CFLAGS_DOUBLE_SUPPORT 0x20
  ------------------
  |  Branch (580:16): [True: 0, False: 3.48k]
  ------------------
  581|       |
  582|       |    ASSIMP_LOG_DEBUG(stream.str());
  583|  3.48k|}
_ZN6Assimp8Importer8ReadFileEPKcj:
  587|  3.48k|const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) {
  588|  3.48k|    ai_assert(nullptr != pimpl);
  589|       |
  590|  3.48k|    ASSIMP_BEGIN_EXCEPTION_REGION();
  591|  3.48k|    const std::string pFile(_pFile);
  592|       |
  593|       |    // ----------------------------------------------------------------------
  594|       |    // Put a large try block around everything to catch all std::exception's
  595|       |    // that might be thrown by STL containers or by new().
  596|       |    // ImportErrorException's are throw by ourselves and caught elsewhere.
  597|       |    //-----------------------------------------------------------------------
  598|       |
  599|  3.48k|    WriteLogOpening(pFile);
  600|       |
  601|       |#ifdef ASSIMP_CATCH_GLOBAL_EXCEPTIONS
  602|       |    try
  603|       |#endif // ! ASSIMP_CATCH_GLOBAL_EXCEPTIONS
  604|  3.48k|    {
  605|       |        // Check whether this Importer instance has already loaded
  606|       |        // a scene. In this case we need to delete the old one
  607|  3.48k|        if (pimpl->mScene)  {
  ------------------
  |  Branch (607:13): [True: 0, False: 3.48k]
  ------------------
  608|       |
  609|      0|            ASSIMP_LOG_DEBUG("(Deleting previous scene)");
  610|      0|            FreeScene();
  611|      0|        }
  612|       |
  613|       |        // First check if the file is accessible at all
  614|  3.48k|        if( !pimpl->mIOHandler->Exists( pFile)) {
  ------------------
  |  Branch (614:13): [True: 0, False: 3.48k]
  ------------------
  615|       |
  616|      0|            pimpl->mErrorString = "Unable to open file \"" + pFile + "\".";
  617|      0|            ASSIMP_LOG_ERROR(pimpl->mErrorString);
  618|      0|            return nullptr;
  619|      0|        }
  620|       |
  621|  3.48k|        std::unique_ptr<Profiler> profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME, 0) ? new Profiler() : nullptr);
  ------------------
  |  Branch (621:44): [True: 0, False: 3.48k]
  ------------------
  622|  3.48k|        if (profiler) {
  ------------------
  |  Branch (622:13): [True: 0, False: 3.48k]
  ------------------
  623|      0|            profiler->BeginRegion("total");
  624|      0|        }
  625|       |
  626|       |        // Find an worker class which can handle the file extension.
  627|       |        // Multiple importers may be able to handle the same extension (.xml!); gather them all.
  628|  3.48k|        SetPropertyInteger("importerIndex", -1);
  629|  3.48k|        struct ImporterAndIndex {
  630|  3.48k|            BaseImporter * importer;
  631|  3.48k|            unsigned int   index;
  632|  3.48k|        };
  633|  3.48k|        std::vector<ImporterAndIndex> possibleImporters;
  634|  10.4k|        for (unsigned int a = 0; a < pimpl->mImporter.size(); a++)  {
  ------------------
  |  Branch (634:34): [True: 6.97k, False: 3.48k]
  ------------------
  635|       |
  636|       |            // Every importer has a list of supported extensions.
  637|  6.97k|            std::set<std::string> extensions;
  638|  6.97k|            pimpl->mImporter[a]->GetExtensionList(extensions);
  639|       |
  640|  6.97k|            if (BaseImporter::HasExtension(pFile, extensions)) {
  ------------------
  |  Branch (640:17): [True: 6.97k, False: 0]
  ------------------
  641|  6.97k|                ImporterAndIndex candidate = { pimpl->mImporter[a], a };
  642|  6.97k|                possibleImporters.push_back(candidate);
  643|  6.97k|            }
  644|  6.97k|        }
  645|       |
  646|       |        // If just one importer supports this extension, pick it and close the case.
  647|  3.48k|        BaseImporter* imp = nullptr;
  648|  3.48k|        if (1 == possibleImporters.size()) {
  ------------------
  |  Branch (648:13): [True: 0, False: 3.48k]
  ------------------
  649|      0|            imp = possibleImporters[0].importer;
  650|      0|            SetPropertyInteger("importerIndex", possibleImporters[0].index);
  651|      0|        }
  652|       |        // If multiple importers claim this file extension, ask them to look at the actual file data to decide.
  653|       |        // This can happen e.g. with XML (COLLADA vs. Irrlicht).
  654|  3.48k|        else {
  655|  7.89k|            for (std::vector<ImporterAndIndex>::const_iterator it = possibleImporters.begin(); it < possibleImporters.end(); ++it) {
  ------------------
  |  Branch (655:96): [True: 6.88k, False: 1.00k]
  ------------------
  656|  6.88k|                BaseImporter & importer = *it->importer;
  657|       |
  658|  6.88k|                ASSIMP_LOG_INFO("Found a possible importer: " + std::string(importer.GetInfo()->mName) + "; trying signature-based detection");
  659|  6.88k|                if (importer.CanRead( pFile, pimpl->mIOHandler, true)) {
  ------------------
  |  Branch (659:21): [True: 2.47k, False: 4.40k]
  ------------------
  660|  2.47k|                    imp = &importer;
  661|  2.47k|                    SetPropertyInteger("importerIndex", it->index);
  662|  2.47k|                    break;
  663|  2.47k|                }
  664|       |
  665|  6.88k|            }
  666|       |
  667|  3.48k|        }
  668|       |
  669|  3.48k|        if (!imp)   {
  ------------------
  |  Branch (669:13): [True: 1.00k, False: 2.47k]
  ------------------
  670|       |            // not so bad yet ... try format auto detection.
  671|  1.00k|            ASSIMP_LOG_INFO("File extension not known, trying signature-based detection");
  672|  3.02k|            for( unsigned int a = 0; a < pimpl->mImporter.size(); a++)  {
  ------------------
  |  Branch (672:38): [True: 2.01k, False: 1.00k]
  ------------------
  673|  2.01k|                if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, true)) {
  ------------------
  |  Branch (673:21): [True: 0, False: 2.01k]
  ------------------
  674|      0|                    imp = pimpl->mImporter[a];
  675|      0|                    SetPropertyInteger("importerIndex", a);
  676|      0|                    break;
  677|      0|                }
  678|  2.01k|            }
  679|       |            // Put a proper error message if no suitable importer was found
  680|  1.00k|            if( !imp)   {
  ------------------
  |  Branch (680:17): [True: 1.00k, False: 0]
  ------------------
  681|  1.00k|                pimpl->mErrorString = "No suitable reader found for the file format of file \"" + pFile + "\".";
  682|  1.00k|                ASSIMP_LOG_ERROR(pimpl->mErrorString);
  683|  1.00k|                return nullptr;
  684|  1.00k|            }
  685|  1.00k|        }
  686|       |
  687|       |        // Get file size for progress handler
  688|  2.47k|        IOStream * fileIO = pimpl->mIOHandler->Open( pFile );
  689|  2.47k|        uint32_t fileSize = 0;
  690|  2.47k|        if (fileIO)
  ------------------
  |  Branch (690:13): [True: 2.47k, False: 0]
  ------------------
  691|  2.47k|        {
  692|  2.47k|            fileSize = static_cast<uint32_t>(fileIO->FileSize());
  693|  2.47k|            pimpl->mIOHandler->Close( fileIO );
  694|  2.47k|        }
  695|       |
  696|       |        // Dispatch the reading to the worker class for this format
  697|  2.47k|        const aiImporterDesc *desc( imp->GetInfo() );
  698|  2.47k|        std::string ext( "unknown" );
  699|  2.47k|        if ( nullptr != desc ) {
  ------------------
  |  Branch (699:14): [True: 2.47k, False: 0]
  ------------------
  700|  2.47k|            ext = desc->mName;
  701|  2.47k|        }
  702|  2.47k|        ASSIMP_LOG_INFO("Found a matching importer for this file format: ", ext, "." );
  703|  2.47k|        pimpl->mProgressHandler->UpdateFileRead( 0, fileSize );
  704|       |
  705|  2.47k|        if (profiler) {
  ------------------
  |  Branch (705:13): [True: 0, False: 2.47k]
  ------------------
  706|      0|            profiler->BeginRegion("import");
  707|      0|        }
  708|       |
  709|  2.47k|        pimpl->mScene = imp->ReadFile( this, pFile, pimpl->mIOHandler);
  710|  2.47k|        pimpl->mProgressHandler->UpdateFileRead( fileSize, fileSize );
  711|       |
  712|  2.47k|        if (profiler) {
  ------------------
  |  Branch (712:13): [True: 0, False: 2.47k]
  ------------------
  713|      0|            profiler->EndRegion("import");
  714|      0|        }
  715|       |
  716|  2.47k|        SetPropertyString("sourceFilePath", pFile);
  717|       |
  718|       |        // If successful, apply all active post processing steps to the imported data
  719|  2.47k|        if( pimpl->mScene)  {
  ------------------
  |  Branch (719:13): [True: 1.62k, False: 855]
  ------------------
  720|  1.62k|            if (!pimpl->mScene->mMetaData || !pimpl->mScene->mMetaData->HasKey(AI_METADATA_SOURCE_FORMAT)) {
  ------------------
  |  Branch (720:17): [True: 0, False: 1.62k]
  |  Branch (720:46): [True: 1.62k, False: 0]
  ------------------
  721|  1.62k|                if (!pimpl->mScene->mMetaData) {
  ------------------
  |  Branch (721:21): [True: 0, False: 1.62k]
  ------------------
  722|      0|                    pimpl->mScene->mMetaData = new aiMetadata;
  723|      0|                }
  724|  1.62k|                pimpl->mScene->mMetaData->Add(AI_METADATA_SOURCE_FORMAT, aiString(ext));
  725|  1.62k|            }
  726|       |
  727|  1.62k|#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
  728|       |            // The ValidateDS process is an exception. It is executed first, even before ScenePreprocessor is called.
  729|  1.62k|            if (pFlags & aiProcess_ValidateDataStructure) {
  ------------------
  |  Branch (729:17): [True: 1.62k, False: 0]
  ------------------
  730|  1.62k|                ValidateDSProcess ds;
  731|  1.62k|                ds.ExecuteOnScene (this);
  732|  1.62k|                if (!pimpl->mScene) {
  ------------------
  |  Branch (732:21): [True: 139, False: 1.48k]
  ------------------
  733|    139|                    return nullptr;
  734|    139|                }
  735|  1.62k|            }
  736|  1.48k|#endif // ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
  737|       |
  738|       |            // Preprocess the scene and prepare it for post-processing
  739|  1.48k|            if (profiler) {
  ------------------
  |  Branch (739:17): [True: 0, False: 1.48k]
  ------------------
  740|      0|                profiler->BeginRegion("preprocess");
  741|      0|            }
  742|       |
  743|  1.48k|            ScenePreprocessor pre(pimpl->mScene);
  744|  1.48k|            pre.ProcessScene();
  745|       |
  746|  1.48k|            if (profiler) {
  ------------------
  |  Branch (746:17): [True: 0, False: 1.48k]
  ------------------
  747|      0|                profiler->EndRegion("preprocess");
  748|      0|            }
  749|       |
  750|       |            // Ensure that the validation process won't be called twice
  751|  1.48k|            ApplyPostProcessing(pFlags & (~aiProcess_ValidateDataStructure));
  752|  1.48k|        }
  753|       |        // if failed, extract the error string
  754|    855|        else if( !pimpl->mScene) {
  ------------------
  |  Branch (754:18): [True: 855, False: 0]
  ------------------
  755|    855|            pimpl->mErrorString = imp->GetErrorText();
  756|    855|            pimpl->mException = imp->GetException();
  757|    855|        }
  758|       |
  759|       |        // clear any data allocated by post-process steps
  760|  2.34k|        pimpl->mPPShared->Clean();
  761|       |
  762|  2.34k|        if (profiler) {
  ------------------
  |  Branch (762:13): [True: 0, False: 2.34k]
  ------------------
  763|      0|            profiler->EndRegion("total");
  764|      0|        }
  765|  2.34k|    }
  766|       |#ifdef ASSIMP_CATCH_GLOBAL_EXCEPTIONS
  767|       |    catch (std::exception &e) {
  768|       |#if (defined _MSC_VER) &&   (defined _CPPRTTI)
  769|       |        // if we have RTTI get the full name of the exception that occurred
  770|       |        pimpl->mErrorString = std::string(typeid( e ).name()) + ": " + e.what();
  771|       |#else
  772|       |        pimpl->mErrorString = std::string("std::exception: ") + e.what();
  773|       |#endif
  774|       |        pimpl->mException = std::current_exception();
  775|       |
  776|       |        ASSIMP_LOG_ERROR(pimpl->mErrorString);
  777|       |        delete pimpl->mScene; pimpl->mScene = nullptr;
  778|       |    }
  779|       |#endif // ! ASSIMP_CATCH_GLOBAL_EXCEPTIONS
  780|       |
  781|       |    // either successful or failure - the pointer expresses it anyways
  782|  2.34k|    ASSIMP_END_EXCEPTION_REGION_WITH_ERROR_STRING(const aiScene*, pimpl->mErrorString, pimpl->mException);
  783|       |
  784|  2.34k|    return pimpl->mScene;
  785|  3.48k|}
_ZN6Assimp8Importer19ApplyPostProcessingEj:
  790|  1.48k|const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) {
  791|  1.48k|    ai_assert(nullptr != pimpl);
  792|       |
  793|  1.48k|    ASSIMP_BEGIN_EXCEPTION_REGION();
  794|       |    // Return immediately if no scene is active
  795|  1.48k|    if (!pimpl->mScene) {
  ------------------
  |  Branch (795:9): [True: 0, False: 1.48k]
  ------------------
  796|      0|        return nullptr;
  797|      0|    }
  798|       |
  799|       |    // If no flags are given, return the current scene with no further action
  800|  1.48k|    if (!pFlags) {
  ------------------
  |  Branch (800:9): [True: 0, False: 1.48k]
  ------------------
  801|      0|        return pimpl->mScene;
  802|      0|    }
  803|       |
  804|       |    // In debug builds: run basic flag validation
  805|  1.48k|    ai_assert(_ValidateFlags(pFlags));
  806|  1.48k|    ASSIMP_LOG_INFO("Entering post processing pipeline");
  807|       |
  808|  1.48k|#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
  809|       |    // The ValidateDS process plays an exceptional role. It isn't contained in the global
  810|       |    // list of post-processing steps, so we need to call it manually.
  811|  1.48k|    if (pFlags & aiProcess_ValidateDataStructure) {
  ------------------
  |  Branch (811:9): [True: 0, False: 1.48k]
  ------------------
  812|      0|        ValidateDSProcess ds;
  813|      0|        ds.ExecuteOnScene (this);
  814|      0|        if (!pimpl->mScene) {
  ------------------
  |  Branch (814:13): [True: 0, False: 0]
  ------------------
  815|      0|            return nullptr;
  816|      0|        }
  817|      0|    }
  818|  1.48k|#endif // no validation
  819|  1.48k|#ifdef ASSIMP_BUILD_DEBUG
  820|  1.48k|    if (pimpl->bExtraVerbose)
  ------------------
  |  Branch (820:9): [True: 0, False: 1.48k]
  ------------------
  821|      0|    {
  822|       |#ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
  823|       |        ASSIMP_LOG_ERROR("Verbose Import is not available due to build settings");
  824|       |#endif  // no validation
  825|      0|        pFlags |= aiProcess_ValidateDataStructure;
  826|      0|    }
  827|       |#else
  828|       |    if (pimpl->bExtraVerbose) {
  829|       |        ASSIMP_LOG_WARN("Not a debug build, ignoring extra verbose setting");
  830|       |    }
  831|       |#endif // ! DEBUG
  832|       |
  833|  1.48k|    std::unique_ptr<Profiler> profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME, 0) ? new Profiler() : nullptr);
  ------------------
  |  Branch (833:40): [True: 0, False: 1.48k]
  ------------------
  834|  49.5k|    for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++)   {
  ------------------
  |  Branch (834:30): [True: 48.1k, False: 1.43k]
  ------------------
  835|  48.1k|        BaseProcess* process = pimpl->mPostProcessingSteps[a];
  836|  48.1k|        pimpl->mProgressHandler->UpdatePostProcess(static_cast<int>(a), static_cast<int>(pimpl->mPostProcessingSteps.size()) );
  837|  48.1k|        if( process->IsActive( pFlags)) {
  ------------------
  |  Branch (837:13): [True: 21.7k, False: 26.3k]
  ------------------
  838|  21.7k|            if (profiler) {
  ------------------
  |  Branch (838:17): [True: 0, False: 21.7k]
  ------------------
  839|      0|                profiler->BeginRegion("postprocess");
  840|      0|            }
  841|       |
  842|  21.7k|            process->ExecuteOnScene ( this );
  843|       |
  844|  21.7k|            if (profiler) {
  ------------------
  |  Branch (844:17): [True: 0, False: 21.7k]
  ------------------
  845|      0|                profiler->EndRegion("postprocess");
  846|      0|            }
  847|  21.7k|        }
  848|  48.1k|        if( !pimpl->mScene) {
  ------------------
  |  Branch (848:13): [True: 53, False: 48.1k]
  ------------------
  849|     53|            break;
  850|     53|        }
  851|  48.1k|#ifdef ASSIMP_BUILD_DEBUG
  852|  48.1k|#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
  853|       |        // If the extra verbose mode is active, execute the ValidateDataStructureStep again - after each step
  854|  48.1k|        if (pimpl->bExtraVerbose)   {
  ------------------
  |  Branch (854:13): [True: 0, False: 48.1k]
  ------------------
  855|      0|            ASSIMP_LOG_DEBUG("Verbose Import: re-validating data structures");
  856|       |
  857|      0|            ValidateDSProcess ds;
  858|      0|            ds.ExecuteOnScene (this);
  859|      0|            if( !pimpl->mScene) {
  ------------------
  |  Branch (859:17): [True: 0, False: 0]
  ------------------
  860|      0|                ASSIMP_LOG_ERROR("Verbose Import: failed to re-validate data structures");
  861|      0|                break;
  862|      0|            }
  863|      0|        }
  864|  48.1k|#endif  // no validation
  865|  48.1k|#endif // ! DEBUG
  866|  48.1k|    }
  867|  1.48k|    pimpl->mProgressHandler->UpdatePostProcess( static_cast<int>(pimpl->mPostProcessingSteps.size()),
  868|  1.48k|        static_cast<int>(pimpl->mPostProcessingSteps.size()) );
  869|       |
  870|       |    // update private scene flags
  871|  1.48k|    if( pimpl->mScene ) {
  ------------------
  |  Branch (871:9): [True: 1.43k, False: 53]
  ------------------
  872|  1.43k|      ScenePriv(pimpl->mScene)->mPPStepsApplied |= pFlags;
  873|  1.43k|    }
  874|       |
  875|       |    // clear any data allocated by post-process steps
  876|  1.48k|    pimpl->mPPShared->Clean();
  877|  1.48k|    ASSIMP_LOG_INFO("Leaving post processing pipeline");
  878|       |
  879|  1.48k|    ASSIMP_END_EXCEPTION_REGION(const aiScene*);
  880|       |
  881|  1.48k|    return pimpl->mScene;
  882|  1.48k|}
_ZNK6Assimp8Importer16GetImporterCountEv:
  969|  3.48k|size_t Importer::GetImporterCount() const {
  970|  3.48k|    ai_assert(nullptr != pimpl);
  971|       |
  972|  3.48k|    return pimpl->mImporter.size();
  973|  3.48k|}
_ZNK6Assimp8Importer15GetImporterInfoEm:
  976|   167k|const aiImporterDesc* Importer::GetImporterInfo(size_t index) const {
  977|   167k|    ai_assert(nullptr != pimpl);
  978|       |
  979|   167k|    if (index >= pimpl->mImporter.size()) {
  ------------------
  |  Branch (979:9): [True: 0, False: 167k]
  ------------------
  980|      0|        return nullptr;
  981|      0|    }
  982|   167k|    return pimpl->mImporter[index]->GetInfo();
  983|   167k|}
_ZNK6Assimp8Importer11GetImporterEm:
  987|   167k|BaseImporter* Importer::GetImporter (size_t index) const {
  988|   167k|    ai_assert(nullptr != pimpl);
  989|       |
  990|   167k|    if (index >= pimpl->mImporter.size()) {
  ------------------
  |  Branch (990:9): [True: 0, False: 167k]
  ------------------
  991|      0|        return nullptr;
  992|      0|    }
  993|   167k|    return pimpl->mImporter[index];
  994|   167k|}
_ZN6Assimp8Importer18SetPropertyIntegerEPKci:
 1063|  5.96k|bool Importer::SetPropertyInteger(const char* szName, int iValue) {
 1064|  5.96k|    ai_assert(nullptr != pimpl);
 1065|       |
 1066|  5.96k|    bool existing;
 1067|  5.96k|    ASSIMP_BEGIN_EXCEPTION_REGION();
 1068|  5.96k|        existing = SetGenericProperty<int>(pimpl->mIntProperties, szName,iValue);
 1069|  5.96k|    ASSIMP_END_EXCEPTION_REGION(bool);
 1070|  5.96k|    return existing;
 1071|  5.96k|}
_ZN6Assimp8Importer16SetPropertyFloatEPKcf:
 1075|  1.62k|bool Importer::SetPropertyFloat(const char* szName, ai_real iValue) {
 1076|  1.62k|    ai_assert(nullptr != pimpl);
 1077|       |
 1078|  1.62k|    bool existing;
 1079|  1.62k|    ASSIMP_BEGIN_EXCEPTION_REGION();
 1080|  1.62k|        existing = SetGenericProperty<ai_real>(pimpl->mFloatProperties, szName,iValue);
 1081|  1.62k|    ASSIMP_END_EXCEPTION_REGION(bool);
 1082|  1.62k|    return existing;
 1083|  1.62k|}
_ZN6Assimp8Importer17SetPropertyStringEPKcRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
 1087|  2.47k|bool Importer::SetPropertyString(const char* szName, const std::string& value) {
 1088|  2.47k|    ai_assert(nullptr != pimpl);
 1089|       |
 1090|  2.47k|    bool existing;
 1091|  2.47k|    ASSIMP_BEGIN_EXCEPTION_REGION();
 1092|  2.47k|        existing = SetGenericProperty<std::string>(pimpl->mStringProperties, szName,value);
 1093|  2.47k|    ASSIMP_END_EXCEPTION_REGION(bool);
 1094|  2.47k|    return existing;
 1095|  2.47k|}
_ZNK6Assimp8Importer18GetPropertyIntegerEPKci:
 1123|  19.5k|int Importer::GetPropertyInteger(const char* szName, int iErrorReturn /*= 0xffffffff*/) const {
 1124|  19.5k|    ai_assert(nullptr != pimpl);
 1125|       |
 1126|  19.5k|    return GetGenericProperty<int>(pimpl->mIntProperties,szName,iErrorReturn);
 1127|  19.5k|}
_ZNK6Assimp8Importer16GetPropertyFloatEPKcf:
 1131|  4.34k|ai_real Importer::GetPropertyFloat(const char* szName, ai_real iErrorReturn /*= 10e10*/) const {
 1132|  4.34k|    ai_assert(nullptr != pimpl);
 1133|       |
 1134|  4.34k|    return GetGenericProperty<ai_real>(pimpl->mFloatProperties,szName,iErrorReturn);
 1135|  4.34k|}
_ZNK6Assimp8Importer17GetPropertyStringEPKcRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
 1139|  1.48k|std::string Importer::GetPropertyString(const char* szName, const std::string& iErrorReturn /*= ""*/) const {
 1140|  1.48k|    ai_assert(nullptr != pimpl);
 1141|       |
 1142|  1.48k|    return GetGenericProperty<std::string>(pimpl->mStringProperties,szName,iErrorReturn);
 1143|  1.48k|}
_ZNK6Assimp8Importer18GetPropertyPointerEPKcPv:
 1155|  2.39k|void* Importer::GetPropertyPointer(const char* szName, void* iErrorReturn /*= nullptr*/) const {
 1156|  2.39k|    ai_assert(nullptr != pimpl);
 1157|       |
 1158|  2.39k|    return GetGenericProperty<void*>(pimpl->mPointerProperties,szName,iErrorReturn);
 1159|  2.39k|}

_ZN6Assimp13ImporterPimplC2Ev:
  137|  3.48k|        mIOHandler( nullptr ),
  138|  3.48k|        mIsDefaultHandler( false ),
  139|  3.48k|        mProgressHandler( nullptr ),
  140|  3.48k|        mIsDefaultProgressHandler( false ),
  141|  3.48k|        mImporter(),
  142|  3.48k|        mPostProcessingSteps(),
  143|  3.48k|        mScene( nullptr ),
  144|  3.48k|        mErrorString(),
  145|  3.48k|        mException(),
  146|  3.48k|        mIntProperties(),
  147|  3.48k|        mFloatProperties(),
  148|  3.48k|        mStringProperties(),
  149|  3.48k|        mMatrixProperties(),
  150|  3.48k|        mPointerProperties(),
  151|  3.48k|        bExtraVerbose( false ),
  152|  3.48k|        mPPShared( nullptr ) {
  153|       |    // empty
  154|  3.48k|}
_ZN6Assimp13ImporterPimplD2Ev:
  133|  3.48k|    ~ImporterPimpl() = default;

_ZN6Assimp23GetImporterInstanceListERNSt3__16vectorIPNS_12BaseImporterENS0_9allocatorIS3_EEEE:
  215|  3.48k|void GetImporterInstanceList(std::vector<BaseImporter *> &out) {
  216|       |
  217|       |    // Some importers may be unimplemented or otherwise unsuitable for general use
  218|       |    // in their current state. Devs can set ASSIMP_ENABLE_DEV_IMPORTERS in their
  219|       |    // local environment to enable them, otherwise they're left out of the registry.
  220|       |#if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP
  221|       |    // not supported under uwp
  222|       |    const char *envStr = std::getenv("ASSIMP_ENABLE_DEV_IMPORTERS");
  223|       |#else
  224|  3.48k|    const char *envStr = { "0" };
  225|  3.48k|#endif
  226|  3.48k|    bool devImportersEnabled = envStr && strcmp(envStr, "0");
  ------------------
  |  Branch (226:32): [True: 3.48k, False: 0]
  |  Branch (226:42): [True: 0, False: 3.48k]
  ------------------
  227|       |
  228|       |    // Ensure no unused var warnings if all uses are #ifndef'd away below:
  229|  3.48k|    (void)devImportersEnabled;
  230|       |
  231|       |    // ----------------------------------------------------------------------------
  232|       |    // Add an instance of each worker class here
  233|       |    // (register_new_importers_here)
  234|       |    // ----------------------------------------------------------------------------
  235|  3.48k|    out.reserve(64);
  236|       |#if !defined(ASSIMP_BUILD_NO_USD_IMPORTER)
  237|       |    out.push_back(new USDImporter());
  238|       |#endif
  239|  3.48k|#if (!defined ASSIMP_BUILD_NO_X_IMPORTER)
  240|  3.48k|    out.push_back(new XFileImporter());
  241|  3.48k|#endif
  242|  3.48k|#if (!defined ASSIMP_BUILD_NO_OBJ_IMPORTER)
  243|  3.48k|    out.push_back(new ObjFileImporter());
  244|  3.48k|#endif
  245|  3.48k|#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
  246|  3.48k|    out.push_back(new AMFImporter());
  247|  3.48k|#endif
  248|  3.48k|#if (!defined ASSIMP_BUILD_NO_3DS_IMPORTER)
  249|  3.48k|    out.push_back(new Discreet3DSImporter());
  250|  3.48k|#endif
  251|       |#if (!defined ASSIMP_BUILD_NO_M3D_IMPORTER)
  252|       |    out.push_back(new M3DImporter());
  253|       |#endif
  254|  3.48k|#if (!defined ASSIMP_BUILD_NO_MD3_IMPORTER)
  255|  3.48k|    out.push_back(new MD3Importer());
  256|  3.48k|#endif
  257|  3.48k|#if (!defined ASSIMP_BUILD_NO_MD2_IMPORTER)
  258|  3.48k|    out.push_back(new MD2Importer());
  259|  3.48k|#endif
  260|  3.48k|#if (!defined ASSIMP_BUILD_NO_PLY_IMPORTER)
  261|  3.48k|    out.push_back(new PLYImporter());
  262|  3.48k|#endif
  263|  3.48k|#if (!defined ASSIMP_BUILD_NO_MDL_IMPORTER)
  264|  3.48k|    out.push_back(new MDLImporter());
  265|  3.48k|#endif
  266|  3.48k|#if (!defined ASSIMP_BUILD_NO_ASE_IMPORTER)
  267|  3.48k|#if (!defined ASSIMP_BUILD_NO_3DS_IMPORTER)
  268|  3.48k|    out.push_back(new ASEImporter());
  269|  3.48k|#endif
  270|  3.48k|#endif
  271|  3.48k|#if (!defined ASSIMP_BUILD_NO_HMP_IMPORTER)
  272|  3.48k|    out.push_back(new HMPImporter());
  273|  3.48k|#endif
  274|  3.48k|#if (!defined ASSIMP_BUILD_NO_SMD_IMPORTER)
  275|  3.48k|    out.push_back(new SMDImporter());
  276|  3.48k|#endif
  277|  3.48k|#if (!defined ASSIMP_BUILD_NO_MDC_IMPORTER)
  278|  3.48k|    out.push_back(new MDCImporter());
  279|  3.48k|#endif
  280|  3.48k|#if (!defined ASSIMP_BUILD_NO_MD5_IMPORTER)
  281|  3.48k|    out.push_back(new MD5Importer());
  282|  3.48k|#endif
  283|  3.48k|#if (!defined ASSIMP_BUILD_NO_STL_IMPORTER)
  284|  3.48k|    out.push_back(new STLImporter());
  285|  3.48k|#endif
  286|  3.48k|#if (!defined ASSIMP_BUILD_NO_LWO_IMPORTER)
  287|  3.48k|    out.push_back(new LWOImporter());
  288|  3.48k|#endif
  289|  3.48k|#if (!defined ASSIMP_BUILD_NO_DXF_IMPORTER)
  290|  3.48k|    out.push_back(new DXFImporter());
  291|  3.48k|#endif
  292|  3.48k|#if (!defined ASSIMP_BUILD_NO_NFF_IMPORTER)
  293|  3.48k|    out.push_back(new NFFImporter());
  294|  3.48k|#endif
  295|  3.48k|#if (!defined ASSIMP_BUILD_NO_RAW_IMPORTER)
  296|  3.48k|    out.push_back(new RAWImporter());
  297|  3.48k|#endif
  298|  3.48k|#if (!defined ASSIMP_BUILD_NO_SIB_IMPORTER)
  299|  3.48k|    out.push_back(new SIBImporter());
  300|  3.48k|#endif
  301|  3.48k|#if (!defined ASSIMP_BUILD_NO_OFF_IMPORTER)
  302|  3.48k|    out.push_back(new OFFImporter());
  303|  3.48k|#endif
  304|  3.48k|#if (!defined ASSIMP_BUILD_NO_AC_IMPORTER)
  305|  3.48k|    out.push_back(new AC3DImporter());
  306|  3.48k|#endif
  307|  3.48k|#if (!defined ASSIMP_BUILD_NO_BVH_IMPORTER)
  308|  3.48k|    out.push_back(new BVHLoader());
  309|  3.48k|#endif
  310|  3.48k|#if (!defined ASSIMP_BUILD_NO_IRRMESH_IMPORTER)
  311|  3.48k|    out.push_back(new IRRMeshImporter());
  312|  3.48k|#endif
  313|  3.48k|#if (!defined ASSIMP_BUILD_NO_IRR_IMPORTER)
  314|  3.48k|    out.push_back(new IRRImporter());
  315|  3.48k|#endif
  316|  3.48k|#if (!defined ASSIMP_BUILD_NO_Q3D_IMPORTER)
  317|  3.48k|    out.push_back(new Q3DImporter());
  318|  3.48k|#endif
  319|  3.48k|#if (!defined ASSIMP_BUILD_NO_B3D_IMPORTER)
  320|  3.48k|    out.push_back(new B3DImporter());
  321|  3.48k|#endif
  322|  3.48k|#if (!defined ASSIMP_BUILD_NO_COLLADA_IMPORTER)
  323|  3.48k|    out.push_back(new ColladaLoader());
  324|  3.48k|#endif
  325|  3.48k|#if (!defined ASSIMP_BUILD_NO_TERRAGEN_IMPORTER)
  326|  3.48k|    out.push_back(new TerragenImporter());
  327|  3.48k|#endif
  328|  3.48k|#if (!defined ASSIMP_BUILD_NO_CSM_IMPORTER)
  329|  3.48k|    out.push_back(new CSMImporter());
  330|  3.48k|#endif
  331|  3.48k|#if (!defined ASSIMP_BUILD_NO_3D_IMPORTER)
  332|  3.48k|    out.push_back(new UnrealImporter());
  333|  3.48k|#endif
  334|  3.48k|#if (!defined ASSIMP_BUILD_NO_LWS_IMPORTER)
  335|  3.48k|    out.push_back(new LWSImporter());
  336|  3.48k|#endif
  337|  3.48k|#if (!defined ASSIMP_BUILD_NO_OGRE_IMPORTER)
  338|  3.48k|    out.push_back(new Ogre::OgreImporter());
  339|  3.48k|#endif
  340|  3.48k|#if (!defined ASSIMP_BUILD_NO_OPENGEX_IMPORTER)
  341|  3.48k|    out.push_back(new OpenGEX::OpenGEXImporter());
  342|  3.48k|#endif
  343|  3.48k|#if (!defined ASSIMP_BUILD_NO_MS3D_IMPORTER)
  344|  3.48k|    out.push_back(new MS3DImporter());
  345|  3.48k|#endif
  346|  3.48k|#if (!defined ASSIMP_BUILD_NO_COB_IMPORTER)
  347|  3.48k|    out.push_back(new COBImporter());
  348|  3.48k|#endif
  349|  3.48k|#if (!defined ASSIMP_BUILD_NO_BLEND_IMPORTER)
  350|  3.48k|    out.push_back(new BlenderImporter());
  351|  3.48k|#endif
  352|  3.48k|#if (!defined ASSIMP_BUILD_NO_Q3BSP_IMPORTER)
  353|  3.48k|    out.push_back(new Q3BSPFileImporter());
  354|  3.48k|#endif
  355|  3.48k|#if (!defined ASSIMP_BUILD_NO_NDO_IMPORTER)
  356|  3.48k|    out.push_back(new NDOImporter());
  357|  3.48k|#endif
  358|  3.48k|#if (!defined ASSIMP_BUILD_NO_IFC_IMPORTER)
  359|  3.48k|    out.push_back(new IFCImporter());
  360|  3.48k|#endif
  361|  3.48k|#if (!defined ASSIMP_BUILD_NO_XGL_IMPORTER)
  362|  3.48k|    out.push_back(new XGLImporter());
  363|  3.48k|#endif
  364|  3.48k|#if (!defined ASSIMP_BUILD_NO_FBX_IMPORTER)
  365|  3.48k|    out.push_back(new FBXImporter());
  366|  3.48k|#endif
  367|  3.48k|#if (!defined ASSIMP_BUILD_NO_ASSBIN_IMPORTER)
  368|  3.48k|    out.push_back(new AssbinImporter());
  369|  3.48k|#endif
  370|  3.48k|#if (!defined ASSIMP_BUILD_NO_GLTF_IMPORTER && !defined ASSIMP_BUILD_NO_GLTF1_IMPORTER)
  371|  3.48k|    out.push_back(new glTFImporter());
  372|  3.48k|#endif
  373|  3.48k|#if (!defined ASSIMP_BUILD_NO_GLTF_IMPORTER && !defined ASSIMP_BUILD_NO_GLTF2_IMPORTER)
  374|  3.48k|    out.push_back(new glTF2Importer());
  375|  3.48k|#endif
  376|       |#if (!defined ASSIMP_BUILD_NO_C4D_IMPORTER)
  377|       |    out.push_back(new C4DImporter());
  378|       |#endif
  379|  3.48k|#if (!defined ASSIMP_BUILD_NO_3MF_IMPORTER)
  380|  3.48k|    out.push_back(new D3MFImporter());
  381|  3.48k|#endif
  382|  3.48k|#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
  383|  3.48k|    out.push_back(new X3DImporter());
  384|  3.48k|#endif
  385|  3.48k|#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
  386|  3.48k|    out.push_back(new MMDImporter());
  387|  3.48k|#endif
  388|  3.48k|#ifndef ASSIMP_BUILD_NO_IQM_IMPORTER
  389|  3.48k|    out.push_back(new IQMImporter());
  390|  3.48k|#endif
  391|  3.48k|}
_ZN6Assimp26DeleteImporterInstanceListERNSt3__16vectorIPNS_12BaseImporterENS0_9allocatorIS3_EEEE:
  394|  3.48k|void DeleteImporterInstanceList(std::vector<BaseImporter *> &deleteList) {
  395|  10.4k|    for (size_t i = 0; i < deleteList.size(); ++i) {
  ------------------
  |  Branch (395:24): [True: 6.97k, False: 3.48k]
  ------------------
  396|  6.97k|        delete deleteList[i];
  397|  6.97k|        deleteList[i] = nullptr;
  398|  6.97k|    } //for
  399|  3.48k|}

_ZN6Assimp33GetPostProcessingStepInstanceListERNSt3__16vectorIPNS_11BaseProcessENS0_9allocatorIS3_EEEE:
  147|  3.48k|{
  148|       |    // ----------------------------------------------------------------------------
  149|       |    // Add an instance of each post processing step here in the order
  150|       |    // of sequence it is executed. Steps that are added here are not
  151|       |    // validated - as RegisterPPStep() does - all dependencies must be given.
  152|       |    // ----------------------------------------------------------------------------
  153|  3.48k|    out.reserve(31);
  154|  3.48k|#if (!defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS)
  155|  3.48k|    out.push_back( new MakeLeftHandedProcess());
  156|  3.48k|#endif
  157|  3.48k|#if (!defined ASSIMP_BUILD_NO_FLIPUVS_PROCESS)
  158|  3.48k|    out.push_back( new FlipUVsProcess());
  159|  3.48k|#endif
  160|  3.48k|#if (!defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS)
  161|  3.48k|    out.push_back( new FlipWindingOrderProcess());
  162|  3.48k|#endif
  163|  3.48k|#if (!defined ASSIMP_BUILD_NO_REMOVEVC_PROCESS)
  164|  3.48k|    out.push_back( new RemoveVCProcess());
  165|  3.48k|#endif
  166|  3.48k|#if (!defined ASSIMP_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS)
  167|  3.48k|    out.push_back( new RemoveRedundantMatsProcess());
  168|  3.48k|#endif
  169|  3.48k|#if (!defined ASSIMP_BUILD_NO_EMBEDTEXTURES_PROCESS)
  170|  3.48k|    out.push_back( new EmbedTexturesProcess());
  171|  3.48k|#endif
  172|  3.48k|#if (!defined ASSIMP_BUILD_NO_FINDINSTANCES_PROCESS)
  173|  3.48k|    out.push_back( new FindInstancesProcess());
  174|  3.48k|#endif
  175|  3.48k|#if (!defined ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS)
  176|  3.48k|    out.push_back( new OptimizeGraphProcess());
  177|  3.48k|#endif
  178|  3.48k|#ifndef ASSIMP_BUILD_NO_GENUVCOORDS_PROCESS
  179|  3.48k|    out.push_back( new ComputeUVMappingProcess());
  180|  3.48k|#endif
  181|  3.48k|#ifndef ASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS
  182|  3.48k|    out.push_back( new TextureTransformStep());
  183|  3.48k|#endif
  184|  3.48k|#if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS)
  185|  3.48k|    out.push_back( new ScaleProcess());
  186|  3.48k|#endif
  187|  3.48k|#if (!defined ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS)
  188|  3.48k|    out.push_back( new ArmaturePopulate());
  189|  3.48k|#endif
  190|  3.48k|#if (!defined ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS)
  191|  3.48k|    out.push_back( new PretransformVertices());
  192|  3.48k|#endif
  193|  3.48k|#if (!defined ASSIMP_BUILD_NO_TRIANGULATE_PROCESS)
  194|  3.48k|    out.push_back( new TriangulateProcess());
  195|  3.48k|#endif
  196|  3.48k|#if (!defined ASSIMP_BUILD_NO_FINDDEGENERATES_PROCESS)
  197|       |    //find degenerates should run after triangulation (to sort out small
  198|       |    //generated triangles) but before sort by p types (in case there are lines
  199|       |    //and points generated and inserted into a mesh)
  200|  3.48k|    out.push_back( new FindDegeneratesProcess());
  201|  3.48k|#endif
  202|  3.48k|#if (!defined ASSIMP_BUILD_NO_SORTBYPTYPE_PROCESS)
  203|  3.48k|    out.push_back( new SortByPTypeProcess());
  204|  3.48k|#endif
  205|  3.48k|#if (!defined ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS)
  206|  3.48k|    out.push_back( new FindInvalidDataProcess());
  207|  3.48k|#endif
  208|  3.48k|#if (!defined ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS)
  209|  3.48k|    out.push_back( new OptimizeMeshesProcess());
  210|  3.48k|#endif
  211|  3.48k|#if (!defined ASSIMP_BUILD_NO_FIXINFACINGNORMALS_PROCESS)
  212|  3.48k|    out.push_back( new FixInfacingNormalsProcess());
  213|  3.48k|#endif
  214|  3.48k|#if (!defined ASSIMP_BUILD_NO_SPLITBYBONECOUNT_PROCESS)
  215|  3.48k|    out.push_back( new SplitByBoneCountProcess());
  216|  3.48k|#endif
  217|  3.48k|#if (!defined ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS)
  218|  3.48k|    out.push_back( new SplitLargeMeshesProcess_Triangle());
  219|  3.48k|#endif
  220|  3.48k|#if (!defined ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS)
  221|  3.48k|    out.push_back( new DropFaceNormalsProcess());
  222|  3.48k|#endif
  223|  3.48k|#if (!defined ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS)
  224|  3.48k|    out.push_back( new GenFaceNormalsProcess());
  225|  3.48k|#endif
  226|       |    // .........................................................................
  227|       |    // DON'T change the order of these five ..
  228|       |    // XXX this is actually a design weakness that dates back to the time
  229|       |    // when Importer would maintain the postprocessing step list exclusively.
  230|       |    // Now that others access it too, we need a better solution.
  231|  3.48k|    out.push_back( new ComputeSpatialSortProcess());
  232|       |    // .........................................................................
  233|       |
  234|  3.48k|#if (!defined ASSIMP_BUILD_NO_GENVERTEXNORMALS_PROCESS)
  235|  3.48k|    out.push_back( new GenVertexNormalsProcess());
  236|  3.48k|#endif
  237|  3.48k|#if (!defined ASSIMP_BUILD_NO_CALCTANGENTS_PROCESS)
  238|  3.48k|    out.push_back( new CalcTangentsProcess());
  239|  3.48k|#endif
  240|  3.48k|#if (!defined ASSIMP_BUILD_NO_JOINVERTICES_PROCESS)
  241|  3.48k|    out.push_back( new JoinVerticesProcess());
  242|  3.48k|#endif
  243|       |
  244|       |    // .........................................................................
  245|  3.48k|    out.push_back( new DestroySpatialSortProcess());
  246|       |    // .........................................................................
  247|       |
  248|  3.48k|#if (!defined ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS)
  249|  3.48k|    out.push_back( new SplitLargeMeshesProcess_Vertex());
  250|  3.48k|#endif
  251|  3.48k|#if (!defined ASSIMP_BUILD_NO_DEBONE_PROCESS)
  252|  3.48k|    out.push_back( new DeboneProcess());
  253|  3.48k|#endif
  254|  3.48k|#if (!defined ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS)
  255|  3.48k|    out.push_back( new LimitBoneWeightsProcess());
  256|  3.48k|#endif
  257|  3.48k|#if (!defined ASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS)
  258|  3.48k|    out.push_back( new ImproveCacheLocalityProcess());
  259|  3.48k|#endif
  260|  3.48k|#if (!defined ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS)
  261|  3.48k|    out.push_back(new GenBoundingBoxesProcess);
  262|  3.48k|#endif
  263|  3.48k|}

_ZN6Assimp17ScenePreprocessor12ProcessSceneEv:
   50|  1.48k|void ScenePreprocessor::ProcessScene() {
   51|  1.48k|    ai_assert(scene != nullptr);
  ------------------
  |  |   67|  1.48k|#   define ai_assert(expression) (void)((!!(expression)) || (Assimp::aiAssertViolation(#expression, __FILE__, __LINE__), 0))
  |  |  ------------------
  |  |  |  Branch (67:41): [True: 1.48k, False: 0]
  |  |  |  Branch (67:61): [True: 0, False: 0]
  |  |  ------------------
  ------------------
   52|       |
   53|       |    // Process all meshes
   54|  2.81k|    for (unsigned int i = 0; i < scene->mNumMeshes; ++i) {
  ------------------
  |  Branch (54:30): [True: 1.32k, False: 1.48k]
  ------------------
   55|  1.32k|        if (nullptr == scene->mMeshes[i]) {
  ------------------
  |  Branch (55:13): [True: 0, False: 1.32k]
  ------------------
   56|      0|            continue;
   57|      0|        }
   58|  1.32k|        ProcessMesh(scene->mMeshes[i]);
   59|  1.32k|    }
   60|       |
   61|       |    // - nothing to do for nodes for the moment
   62|       |    // - nothing to do for textures for the moment
   63|       |    // - nothing to do for lights for the moment
   64|       |    // - nothing to do for cameras for the moment
   65|       |
   66|       |    // Process all animations
   67|  1.48k|    for (unsigned int i = 0; i < scene->mNumAnimations; ++i) {
  ------------------
  |  Branch (67:30): [True: 0, False: 1.48k]
  ------------------
   68|      0|        if (nullptr == scene->mAnimations[i]) {
  ------------------
  |  Branch (68:13): [True: 0, False: 0]
  ------------------
   69|      0|            continue;
   70|      0|        }
   71|      0|        ProcessAnimation(scene->mAnimations[i]);
   72|      0|    }
   73|       |
   74|       |    // Generate a default material if none was specified
   75|  1.48k|    if (!scene->mNumMaterials && scene->mNumMeshes) {
  ------------------
  |  Branch (75:9): [True: 0, False: 1.48k]
  |  Branch (75:34): [True: 0, False: 0]
  ------------------
   76|      0|        scene->mMaterials = new aiMaterial *[2];
   77|      0|        aiMaterial *helper;
   78|       |
   79|      0|        aiString name;
   80|       |
   81|      0|        scene->mMaterials[scene->mNumMaterials] = helper = new aiMaterial();
   82|      0|        aiColor3D clr(0.6f, 0.6f, 0.6f);
   83|      0|        helper->AddProperty(&clr, 1, AI_MATKEY_COLOR_DIFFUSE);
   84|       |
   85|       |        // setup the default name to make this material identifiable
   86|      0|        name.Set(AI_DEFAULT_MATERIAL_NAME);
   87|      0|        helper->AddProperty(&name, AI_MATKEY_NAME);
   88|       |
   89|      0|        ASSIMP_LOG_DEBUG("ScenePreprocessor: Adding default material \'" AI_DEFAULT_MATERIAL_NAME "\'");
   90|       |
   91|      0|        for (unsigned int i = 0; i < scene->mNumMeshes; ++i) {
  ------------------
  |  Branch (91:34): [True: 0, False: 0]
  ------------------
   92|      0|            if (nullptr == scene->mMeshes[i]) {
  ------------------
  |  Branch (92:17): [True: 0, False: 0]
  ------------------
   93|      0|                continue;
   94|      0|            }
   95|      0|            scene->mMeshes[i]->mMaterialIndex = scene->mNumMaterials;
   96|      0|        }
   97|       |
   98|      0|        scene->mNumMaterials++;
   99|      0|    }
  100|  1.48k|}
_ZN6Assimp17ScenePreprocessor11ProcessMeshEP6aiMesh:
  103|  1.32k|void ScenePreprocessor::ProcessMesh(aiMesh *mesh) {
  104|       |    // If aiMesh::mNumUVComponents is *not* set assign the default value of 2
  105|  11.9k|    for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
  ------------------
  |  Branch (105:30): [True: 10.6k, False: 1.32k]
  ------------------
  106|  10.6k|        if (!mesh->mTextureCoords[i]) {
  ------------------
  |  Branch (106:13): [True: 10.2k, False: 338]
  ------------------
  107|  10.2k|            mesh->mNumUVComponents[i] = 0;
  108|  10.2k|            continue;
  109|  10.2k|        }
  110|       |
  111|    338|        if (!mesh->mNumUVComponents[i]) {
  ------------------
  |  Branch (111:13): [True: 0, False: 338]
  ------------------
  112|      0|            mesh->mNumUVComponents[i] = 2;
  113|      0|        }
  114|       |
  115|    338|        aiVector3D *p = mesh->mTextureCoords[i], *end = p + mesh->mNumVertices;
  116|       |
  117|       |        // Ensure unused components are zeroed. This will make 1D texture channels work
  118|       |        // as if they were 2D channels .. just in case an application doesn't handle
  119|       |        // this case
  120|    338|        if (2 == mesh->mNumUVComponents[i]) {
  ------------------
  |  Branch (120:13): [True: 280, False: 58]
  ------------------
  121|  2.75k|            for (; p != end; ++p) {
  ------------------
  |  Branch (121:20): [True: 2.47k, False: 280]
  ------------------
  122|  2.47k|                p->z = 0.f;
  123|  2.47k|            }
  124|    280|        } else if (1 == mesh->mNumUVComponents[i]) {
  ------------------
  |  Branch (124:20): [True: 36, False: 22]
  ------------------
  125|    484|            for (; p != end; ++p) {
  ------------------
  |  Branch (125:20): [True: 448, False: 36]
  ------------------
  126|    448|                p->z = p->y = 0.f;
  127|    448|            }
  128|     36|        } else if (3 == mesh->mNumUVComponents[i]) {
  ------------------
  |  Branch (128:20): [True: 13, False: 9]
  ------------------
  129|       |            // Really 3D coordinates? Check whether the third coordinate is != 0 for at least one element
  130|    106|            for (; p != end; ++p) {
  ------------------
  |  Branch (130:20): [True: 102, False: 4]
  ------------------
  131|    102|                if (p->z != 0) {
  ------------------
  |  Branch (131:21): [True: 9, False: 93]
  ------------------
  132|      9|                    break;
  133|      9|                }
  134|    102|            }
  135|     13|            if (p == end) {
  ------------------
  |  Branch (135:17): [True: 4, False: 9]
  ------------------
  136|      4|                ASSIMP_LOG_WARN("ScenePreprocessor: UVs are declared to be 3D but they're obviously not. Reverting to 2D.");
  137|      4|                mesh->mNumUVComponents[i] = 2;
  138|      4|            }
  139|     13|        }
  140|    338|    }
  141|       |
  142|       |    // If the information which primitive types are there in the
  143|       |    // mesh is currently not available, compute it.
  144|  1.32k|    if (!mesh->mPrimitiveTypes) {
  ------------------
  |  Branch (144:9): [True: 0, False: 1.32k]
  ------------------
  145|      0|        ai_assert(mesh->mFaces != nullptr);
  ------------------
  |  |   67|      0|#   define ai_assert(expression) (void)((!!(expression)) || (Assimp::aiAssertViolation(#expression, __FILE__, __LINE__), 0))
  |  |  ------------------
  |  |  |  Branch (67:41): [True: 0, False: 0]
  |  |  |  Branch (67:61): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  146|      0|        for (unsigned int a = 0; a < mesh->mNumFaces; ++a) {
  ------------------
  |  Branch (146:34): [True: 0, False: 0]
  ------------------
  147|      0|            aiFace &face = mesh->mFaces[a];
  148|      0|            switch (face.mNumIndices) {
  149|      0|            case 3u:
  ------------------
  |  Branch (149:13): [True: 0, False: 0]
  ------------------
  150|      0|                mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
  151|      0|                break;
  152|       |
  153|      0|            case 2u:
  ------------------
  |  Branch (153:13): [True: 0, False: 0]
  ------------------
  154|      0|                mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
  155|      0|                break;
  156|       |
  157|      0|            case 1u:
  ------------------
  |  Branch (157:13): [True: 0, False: 0]
  ------------------
  158|      0|                mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
  159|      0|                break;
  160|       |
  161|      0|            default:
  ------------------
  |  Branch (161:13): [True: 0, False: 0]
  ------------------
  162|      0|                mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
  163|      0|                break;
  164|      0|            }
  165|      0|        }
  166|      0|    }
  167|       |
  168|       |    // If tangents and normals are given but no bitangents compute them
  169|  1.32k|    if (mesh->mTangents && mesh->mNormals && !mesh->mBitangents) {
  ------------------
  |  Branch (169:9): [True: 32, False: 1.29k]
  |  Branch (169:28): [True: 32, False: 0]
  |  Branch (169:46): [True: 0, False: 32]
  ------------------
  170|      0|        mesh->mBitangents = new aiVector3D[mesh->mNumVertices];
  171|      0|        for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
  ------------------
  |  Branch (171:34): [True: 0, False: 0]
  ------------------
  172|      0|            mesh->mBitangents[i] = mesh->mNormals[i] ^ mesh->mTangents[i];
  173|      0|        }
  174|      0|    }
  175|  1.32k|}

_ZN6Assimp17ScenePreprocessorC2EP7aiScene:
   79|  1.48k|            scene(_scene) {}

_ZN6Assimp9ScenePrivEP7aiScene:
   85|  1.43k|ScenePrivateData* ScenePriv(aiScene* in) {
   86|  1.43k|    ai_assert( nullptr != in );
   87|  1.43k|    if ( nullptr == in ) {
  ------------------
  |  Branch (87:10): [True: 0, False: 1.43k]
  ------------------
   88|      0|        return nullptr;
   89|      0|    }
   90|  1.43k|    return static_cast<ScenePrivateData*>(in->mPrivate);
   91|  1.43k|}
_ZN6Assimp16ScenePrivateDataC2Ev:
   77|  2.47k|: mOrigImporter( nullptr )
   78|  2.47k|, mPPStepsApplied( 0 )
   79|  2.47k|, mIsCopy( false ) {
   80|       |    // empty
   81|  2.47k|}

_ZN6Assimp11SpatialSortC2Ev:
   69|  2.90k|        mPlaneNormal(PlaneInit),
   70|  2.90k|        mFinalized(false) {
   71|  2.90k|    mPlaneNormal.Normalize();
   72|  2.90k|}
_ZN6Assimp11SpatialSort4FillEPK10aiVector3tIfEjjb:
   77|  2.11k|        bool pFinalize /*= true */) {
   78|  2.11k|    mPositions.clear();
   79|  2.11k|    mFinalized = false;
   80|  2.11k|    Append(pPositions, pNumPositions, pElementOffset, pFinalize);
   81|  2.11k|    mFinalized = pFinalize;
   82|  2.11k|}
_ZNK6Assimp11SpatialSort17CalculateDistanceERK10aiVector3tIfE:
   85|   119k|ai_real SpatialSort::CalculateDistance(const aiVector3D &pPosition) const {
   86|   119k|    return (pPosition - mCentroid) * mPlaneNormal;
   87|   119k|}
_ZN6Assimp11SpatialSort8FinalizeEv:
   90|  2.11k|void SpatialSort::Finalize() {
   91|  2.11k|    const ai_real scale = 1.0f / mPositions.size();
   92|  74.9k|    for (unsigned int i = 0; i < mPositions.size(); i++) {
  ------------------
  |  Branch (92:30): [True: 72.8k, False: 2.11k]
  ------------------
   93|  72.8k|        mCentroid += scale * mPositions[i].mPosition;
   94|  72.8k|    }
   95|  74.9k|    for (unsigned int i = 0; i < mPositions.size(); i++) {
  ------------------
  |  Branch (95:30): [True: 72.8k, False: 2.11k]
  ------------------
   96|  72.8k|        mPositions[i].mDistance = CalculateDistance(mPositions[i].mPosition);
   97|  72.8k|    }
   98|  2.11k|    std::sort(mPositions.begin(), mPositions.end());
   99|  2.11k|    mFinalized = true;
  100|  2.11k|}
_ZN6Assimp11SpatialSort6AppendEPK10aiVector3tIfEjjb:
  105|  2.11k|        bool pFinalize /*= true */) {
  106|  2.11k|    ai_assert(!mFinalized && "You cannot add positions to the SpatialSort object after it has been finalized.");
  ------------------
  |  |   67|  4.23k|#   define ai_assert(expression) (void)((!!(expression)) || (Assimp::aiAssertViolation(#expression, __FILE__, __LINE__), 0))
  |  |  ------------------
  |  |  |  Branch (67:45): [True: 2.11k, False: 0]
  |  |  |  Branch (67:45): [True: 0, Folded]
  |  |  |  Branch (67:61): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  107|       |    // store references to all given positions along with their distance to the reference plane
  108|  2.11k|    const size_t initial = mPositions.size();
  109|  2.11k|    mPositions.reserve(initial + pNumPositions);
  110|  74.9k|    for (unsigned int a = 0; a < pNumPositions; a++) {
  ------------------
  |  Branch (110:30): [True: 72.8k, False: 2.11k]
  ------------------
  111|  72.8k|        const char *tempPointer = reinterpret_cast<const char *>(pPositions);
  112|  72.8k|        const aiVector3D *vec = reinterpret_cast<const aiVector3D *>(tempPointer + a * pElementOffset);
  113|  72.8k|        mPositions.emplace_back(static_cast<unsigned int>(a + initial), *vec);
  114|  72.8k|    }
  115|       |
  116|  2.11k|    if (pFinalize) {
  ------------------
  |  Branch (116:9): [True: 2.11k, False: 0]
  ------------------
  117|       |        // now sort the array ascending by distance.
  118|  2.11k|        Finalize();
  119|  2.11k|    }
  120|  2.11k|}
_ZNK6Assimp11SpatialSort13FindPositionsERK10aiVector3tIfEfRNSt3__16vectorIjNS5_9allocatorIjEEEE:
  125|  46.6k|        ai_real pRadius, std::vector<unsigned int> &poResults) const {
  126|  46.6k|    ai_assert(mFinalized && "The SpatialSort object must be finalized before FindPositions can be called.");
  ------------------
  |  |   67|  93.3k|#   define ai_assert(expression) (void)((!!(expression)) || (Assimp::aiAssertViolation(#expression, __FILE__, __LINE__), 0))
  |  |  ------------------
  |  |  |  Branch (67:45): [True: 46.6k, False: 0]
  |  |  |  Branch (67:45): [True: 0, Folded]
  |  |  |  Branch (67:61): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  127|  46.6k|    const ai_real dist = CalculateDistance(pPosition);
  128|  46.6k|    const ai_real minDist = dist - pRadius, maxDist = dist + pRadius;
  129|       |
  130|       |    // clear the array
  131|  46.6k|    poResults.clear();
  132|       |
  133|       |    // quick check for positions outside the range
  134|  46.6k|    if (mPositions.size() == 0)
  ------------------
  |  Branch (134:9): [True: 0, False: 46.6k]
  ------------------
  135|      0|        return;
  136|  46.6k|    if (maxDist < mPositions.front().mDistance)
  ------------------
  |  Branch (136:9): [True: 0, False: 46.6k]
  ------------------
  137|      0|        return;
  138|  46.6k|    if (minDist > mPositions.back().mDistance)
  ------------------
  |  Branch (138:9): [True: 0, False: 46.6k]
  ------------------
  139|      0|        return;
  140|       |
  141|       |    // do a binary search for the minimal distance to start the iteration there
  142|  46.6k|    unsigned int index = (unsigned int)mPositions.size() / 2;
  143|  46.6k|    unsigned int binaryStepSize = (unsigned int)mPositions.size() / 4;
  144|   256k|    while (binaryStepSize > 1) {
  ------------------
  |  Branch (144:12): [True: 209k, False: 46.6k]
  ------------------
  145|   209k|        if (mPositions[index].mDistance < minDist)
  ------------------
  |  Branch (145:13): [True: 89.9k, False: 119k]
  ------------------
  146|  89.9k|            index += binaryStepSize;
  147|   119k|        else
  148|   119k|            index -= binaryStepSize;
  149|       |
  150|   209k|        binaryStepSize /= 2;
  151|   209k|    }
  152|       |
  153|       |    // depending on the direction of the last step we need to single step a bit back or forth
  154|       |    // to find the actual beginning element of the range
  155|  65.8k|    while (index > 0 && mPositions[index].mDistance > minDist)
  ------------------
  |  Branch (155:12): [True: 61.3k, False: 4.48k]
  |  Branch (155:25): [True: 19.1k, False: 42.1k]
  ------------------
  156|  19.1k|        index--;
  157|  87.9k|    while (index < (mPositions.size() - 1) && mPositions[index].mDistance < minDist)
  ------------------
  |  Branch (157:12): [True: 87.7k, False: 178]
  |  Branch (157:47): [True: 41.2k, False: 46.5k]
  ------------------
  158|  41.2k|        index++;
  159|       |
  160|       |    // Mow start iterating from there until the first position lays outside of the distance range.
  161|       |    // Add all positions inside the distance range within the given radius to the result array
  162|  46.6k|    std::vector<Entry>::const_iterator it = mPositions.begin() + index;
  163|  46.6k|    const ai_real pSquared = pRadius * pRadius;
  164|   218k|    while (it->mDistance < maxDist) {
  ------------------
  |  Branch (164:12): [True: 175k, False: 42.6k]
  ------------------
  165|   175k|        if ((it->mPosition - pPosition).SquareLength() < pSquared)
  ------------------
  |  Branch (165:13): [True: 55.8k, False: 119k]
  ------------------
  166|  55.8k|            poResults.push_back(it->mIndex);
  167|   175k|        ++it;
  168|   175k|        if (it == mPositions.end())
  ------------------
  |  Branch (168:13): [True: 4.04k, False: 171k]
  ------------------
  169|  4.04k|            break;
  170|   175k|    }
  171|       |
  172|       |    // that's it
  173|  46.6k|}

aiGetVersionMinor:
   72|  3.48k|ASSIMP_API unsigned int aiGetVersionMinor() {
   73|  3.48k|    return VER_MINOR;
  ------------------
  |  |    8|  3.48k|#define VER_MINOR 0
  ------------------
   74|  3.48k|}
aiGetVersionMajor:
   78|  3.48k|ASSIMP_API unsigned int aiGetVersionMajor() {
   79|  3.48k|    return VER_MAJOR;
  ------------------
  |  |    7|  3.48k|#define VER_MAJOR 6
  ------------------
   80|  3.48k|}
aiGetCompileFlags:
   84|  3.48k|ASSIMP_API unsigned int aiGetCompileFlags() {
   85|       |
   86|  3.48k|    unsigned int flags = 0;
   87|       |
   88|       |#ifdef ASSIMP_BUILD_BOOST_WORKAROUND
   89|       |    flags |= ASSIMP_CFLAGS_NOBOOST;
   90|       |#endif
   91|  3.48k|#ifdef ASSIMP_BUILD_SINGLETHREADED
   92|  3.48k|    flags |= ASSIMP_CFLAGS_SINGLETHREADED;
  ------------------
  |  |  107|  3.48k|#define ASSIMP_CFLAGS_SINGLETHREADED    0x10
  ------------------
   93|  3.48k|#endif
   94|  3.48k|#ifdef ASSIMP_BUILD_DEBUG
   95|  3.48k|    flags |= ASSIMP_CFLAGS_DEBUG;
  ------------------
  |  |  102|  3.48k|#define ASSIMP_CFLAGS_DEBUG   0x4
  ------------------
   96|  3.48k|#endif
   97|       |#ifdef ASSIMP_BUILD_DLL_EXPORT
   98|       |    flags |= ASSIMP_CFLAGS_SHARED;
   99|       |#endif
  100|       |#ifdef _STLPORT_VERSION
  101|       |    flags |= ASSIMP_CFLAGS_STLPORT;
  102|       |#endif
  103|       |#ifdef ASSIMP_DOUBLE_PRECISION
  104|       |    flags |= ASSIMP_CFLAGS_DOUBLE_SUPPORT;
  105|       |#endif
  106|       |
  107|  3.48k|    return flags;
  108|  3.48k|}
aiGetVersionRevision:
  111|  3.48k|ASSIMP_API unsigned int aiGetVersionRevision() {
  112|  3.48k|    return GitVersion;
  ------------------
  |  |    4|  3.48k|#define GitVersion 0x0404c875
  ------------------
  113|  3.48k|}

_ZN6Assimp23VertexTriangleAdjacencyC2EP6aiFacejjb:
   55|    424|        bool bComputeNumTriangles /*= false*/) {
   56|       |    // compute the number of referenced vertices if it wasn't specified by the caller
   57|    424|    const aiFace *const pcFaceEnd = pcFaces + iNumFaces;
   58|    424|    if (0 == iNumVertices) {
  ------------------
  |  Branch (58:9): [True: 0, False: 424]
  ------------------
   59|      0|        for (aiFace *pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace) {
  ------------------
  |  Branch (59:40): [True: 0, False: 0]
  ------------------
   60|      0|            ai_assert(nullptr != pcFace);
   61|      0|            ai_assert(3 == pcFace->mNumIndices);
   62|      0|            iNumVertices = std::max(iNumVertices, pcFace->mIndices[0]);
   63|      0|            iNumVertices = std::max(iNumVertices, pcFace->mIndices[1]);
   64|      0|            iNumVertices = std::max(iNumVertices, pcFace->mIndices[2]);
   65|      0|        }
   66|      0|    }
   67|       |
   68|    424|    mNumVertices = iNumVertices + 1;
   69|       |
   70|    424|    unsigned int *pi;
   71|       |
   72|       |    // allocate storage
   73|    424|    if (bComputeNumTriangles) {
  ------------------
  |  Branch (73:9): [True: 424, False: 0]
  ------------------
   74|    424|        pi = mLiveTriangles = new unsigned int[iNumVertices + 1];
   75|    424|        ::memset(mLiveTriangles, 0, sizeof(unsigned int) * (iNumVertices + 1));
   76|    424|        mOffsetTable = new unsigned int[iNumVertices + 2] + 1;
   77|    424|    } else {
   78|      0|        pi = mOffsetTable = new unsigned int[iNumVertices + 2] + 1;
   79|      0|        ::memset(mOffsetTable, 0, sizeof(unsigned int) * (iNumVertices + 1));
   80|      0|        mLiveTriangles = nullptr; // important, otherwise the d'tor would crash
   81|      0|    }
   82|       |
   83|       |    // get a pointer to the end of the buffer
   84|    424|    unsigned int *piEnd = pi + iNumVertices;
   85|    424|    *piEnd++ = 0u;
   86|       |
   87|       |    // first pass: compute the number of faces referencing each vertex
   88|  16.0k|    for (aiFace *pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace) {
  ------------------
  |  Branch (88:36): [True: 15.5k, False: 424]
  ------------------
   89|  15.5k|        unsigned nind = pcFace->mNumIndices;
   90|  15.5k|        unsigned *ind = pcFace->mIndices;
   91|  15.5k|        if (nind > 0) pi[ind[0]]++;
  ------------------
  |  Branch (91:13): [True: 15.5k, False: 0]
  ------------------
   92|  15.5k|        if (nind > 1) pi[ind[1]]++;
  ------------------
  |  Branch (92:13): [True: 15.5k, False: 0]
  ------------------
   93|  15.5k|        if (nind > 2) pi[ind[2]]++;
  ------------------
  |  Branch (93:13): [True: 15.5k, False: 0]
  ------------------
   94|  15.5k|    }
   95|       |
   96|       |    // second pass: compute the final offset table
   97|    424|    unsigned int iSum = 0;
   98|    424|    unsigned int *piCurOut = this->mOffsetTable;
   99|  13.1k|    for (unsigned int *piCur = pi; piCur != piEnd; ++piCur, ++piCurOut) {
  ------------------
  |  Branch (99:36): [True: 12.7k, False: 424]
  ------------------
  100|       |
  101|  12.7k|        unsigned int iLastSum = iSum;
  102|  12.7k|        iSum += *piCur;
  103|  12.7k|        *piCurOut = iLastSum;
  104|  12.7k|    }
  105|    424|    pi = this->mOffsetTable;
  106|       |
  107|       |    // third pass: compute the final table
  108|    424|    this->mAdjacencyTable = new unsigned int[iSum];
  109|    424|    iSum = 0;
  110|  16.0k|    for (aiFace *pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace, ++iSum) {
  ------------------
  |  Branch (110:36): [True: 15.5k, False: 424]
  ------------------
  111|  15.5k|        unsigned nind = pcFace->mNumIndices;
  112|  15.5k|        unsigned *ind = pcFace->mIndices;
  113|       |
  114|  15.5k|        if (nind > 0) mAdjacencyTable[pi[ind[0]]++] = iSum;
  ------------------
  |  Branch (114:13): [True: 15.5k, False: 0]
  ------------------
  115|  15.5k|        if (nind > 1) mAdjacencyTable[pi[ind[1]]++] = iSum;
  ------------------
  |  Branch (115:13): [True: 15.5k, False: 0]
  ------------------
  116|  15.5k|        if (nind > 2) mAdjacencyTable[pi[ind[2]]++] = iSum;
  ------------------
  |  Branch (116:13): [True: 15.5k, False: 0]
  ------------------
  117|  15.5k|    }
  118|       |    // fourth pass: undo the offset computations made during the third pass
  119|       |    // We could do this in a separate buffer, but this would be TIMES slower.
  120|    424|    --mOffsetTable;
  121|    424|    *mOffsetTable = 0u;
  122|    424|}
_ZN6Assimp23VertexTriangleAdjacencyD2Ev:
  124|    424|VertexTriangleAdjacency::~VertexTriangleAdjacency() {
  125|       |    // delete allocated storage
  126|    424|    delete[] mOffsetTable;
  127|    424|    delete[] mAdjacencyTable;
  128|    424|    delete[] mLiveTriangles;
  129|    424|}

_ZNK6Assimp23VertexTriangleAdjacency20GetAdjacentTrianglesEj:
   85|  5.90k|    unsigned int* GetAdjacentTriangles(unsigned int iVertIndex) const {
   86|       |        ai_assert(iVertIndex < mNumVertices);
   87|  5.90k|        return &mAdjacencyTable[ mOffsetTable[iVertIndex]];
   88|  5.90k|    }

aiTextureTypeToString:
   49|  43.3k|const char *aiTextureTypeToString(aiTextureType in) {
   50|  43.3k|    switch (in) {
   51|      0|    case aiTextureType_NONE:
  ------------------
  |  Branch (51:5): [True: 0, False: 43.3k]
  ------------------
   52|      0|        return "n/a";
   53|  2.55k|    case aiTextureType_DIFFUSE:
  ------------------
  |  Branch (53:5): [True: 2.55k, False: 40.8k]
  ------------------
   54|  2.55k|        return "Diffuse";
   55|  2.55k|    case aiTextureType_SPECULAR:
  ------------------
  |  Branch (55:5): [True: 2.55k, False: 40.8k]
  ------------------
   56|  2.55k|        return "Specular";
   57|  2.55k|    case aiTextureType_AMBIENT:
  ------------------
  |  Branch (57:5): [True: 2.55k, False: 40.8k]
  ------------------
   58|  2.55k|        return "Ambient";
   59|  2.55k|    case aiTextureType_EMISSIVE:
  ------------------
  |  Branch (59:5): [True: 2.55k, False: 40.8k]
  ------------------
   60|  2.55k|        return "Emissive";
   61|  2.55k|    case aiTextureType_OPACITY:
  ------------------
  |  Branch (61:5): [True: 2.55k, False: 40.8k]
  ------------------
   62|  2.55k|        return "Opacity";
   63|  2.55k|    case aiTextureType_NORMALS:
  ------------------
  |  Branch (63:5): [True: 2.55k, False: 40.8k]
  ------------------
   64|  2.55k|        return "Normals";
   65|  2.55k|    case aiTextureType_HEIGHT:
  ------------------
  |  Branch (65:5): [True: 2.55k, False: 40.8k]
  ------------------
   66|  2.55k|        return "Height";
   67|  2.55k|    case aiTextureType_SHININESS:
  ------------------
  |  Branch (67:5): [True: 2.55k, False: 40.8k]
  ------------------
   68|  2.55k|        return "Shininess";
   69|  2.55k|    case aiTextureType_DISPLACEMENT:
  ------------------
  |  Branch (69:5): [True: 2.55k, False: 40.8k]
  ------------------
   70|  2.55k|        return "Displacement";
   71|  2.55k|    case aiTextureType_LIGHTMAP:
  ------------------
  |  Branch (71:5): [True: 2.55k, False: 40.8k]
  ------------------
   72|  2.55k|        return "Lightmap";
   73|  2.55k|    case aiTextureType_REFLECTION:
  ------------------
  |  Branch (73:5): [True: 2.55k, False: 40.8k]
  ------------------
   74|  2.55k|        return "Reflection";
   75|  2.55k|    case aiTextureType_BASE_COLOR:
  ------------------
  |  Branch (75:5): [True: 2.55k, False: 40.8k]
  ------------------
   76|  2.55k|        return "BaseColor";
   77|  2.55k|    case aiTextureType_NORMAL_CAMERA:
  ------------------
  |  Branch (77:5): [True: 2.55k, False: 40.8k]
  ------------------
   78|  2.55k|        return "NormalCamera";
   79|  2.55k|    case aiTextureType_EMISSION_COLOR:
  ------------------
  |  Branch (79:5): [True: 2.55k, False: 40.8k]
  ------------------
   80|  2.55k|        return "EmissionColor";
   81|  2.55k|    case aiTextureType_METALNESS:
  ------------------
  |  Branch (81:5): [True: 2.55k, False: 40.8k]
  ------------------
   82|  2.55k|        return "Metalness";
   83|  2.55k|    case aiTextureType_DIFFUSE_ROUGHNESS:
  ------------------
  |  Branch (83:5): [True: 2.55k, False: 40.8k]
  ------------------
   84|  2.55k|        return "DiffuseRoughness";
   85|  2.55k|    case aiTextureType_AMBIENT_OCCLUSION:
  ------------------
  |  Branch (85:5): [True: 2.55k, False: 40.8k]
  ------------------
   86|  2.55k|        return "AmbientOcclusion";
   87|      0|    case aiTextureType_SHEEN:
  ------------------
  |  Branch (87:5): [True: 0, False: 43.3k]
  ------------------
   88|      0|        return "Sheen";
   89|      0|    case aiTextureType_CLEARCOAT:
  ------------------
  |  Branch (89:5): [True: 0, False: 43.3k]
  ------------------
   90|      0|        return "Clearcoat";
   91|      0|    case aiTextureType_TRANSMISSION:
  ------------------
  |  Branch (91:5): [True: 0, False: 43.3k]
  ------------------
   92|      0|        return "Transmission";
   93|      0|    case aiTextureType_MAYA_BASE:
  ------------------
  |  Branch (93:5): [True: 0, False: 43.3k]
  ------------------
   94|      0|        return "MayaBase";
   95|      0|    case aiTextureType_MAYA_SPECULAR:
  ------------------
  |  Branch (95:5): [True: 0, False: 43.3k]
  ------------------
   96|      0|        return "MayaSpecular";
   97|      0|    case aiTextureType_MAYA_SPECULAR_COLOR:
  ------------------
  |  Branch (97:5): [True: 0, False: 43.3k]
  ------------------
   98|      0|        return "MayaSpecularColor";
   99|      0|    case aiTextureType_MAYA_SPECULAR_ROUGHNESS:
  ------------------
  |  Branch (99:5): [True: 0, False: 43.3k]
  ------------------
  100|      0|        return "MayaSpecularRoughness";
  101|      0|    case aiTextureType_ANISOTROPY:
  ------------------
  |  Branch (101:5): [True: 0, False: 43.3k]
  ------------------
  102|      0|        return "Anisotropy";
  103|      0|    case aiTextureType_GLTF_METALLIC_ROUGHNESS:
  ------------------
  |  Branch (103:5): [True: 0, False: 43.3k]
  ------------------
  104|      0|        return "glTFMetallicRoughness";
  105|      0|    case aiTextureType_UNKNOWN:
  ------------------
  |  Branch (105:5): [True: 0, False: 43.3k]
  ------------------
  106|      0|        return "Unknown";
  107|      0|    default:
  ------------------
  |  Branch (107:5): [True: 0, False: 43.3k]
  ------------------
  108|      0|        break;
  109|  43.3k|    }
  110|      0|    ai_assert(false);
  ------------------
  |  |   67|      0|#   define ai_assert(expression) (void)((!!(expression)) || (Assimp::aiAssertViolation(#expression, __FILE__, __LINE__), 0))
  |  |  ------------------
  |  |  |  Branch (67:41): [Folded, False: 0]
  |  |  |  Branch (67:61): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  111|      0|    return "BUG";
  112|  43.3k|}

_ZN7aiSceneC2Ev:
   46|  2.47k|        mFlags(0),
   47|  2.47k|        mRootNode(nullptr),
   48|  2.47k|        mNumMeshes(0),
   49|  2.47k|        mMeshes(nullptr),
   50|  2.47k|        mNumMaterials(0),
   51|  2.47k|        mMaterials(nullptr),
   52|  2.47k|        mNumAnimations(0),
   53|  2.47k|        mAnimations(nullptr),
   54|  2.47k|        mNumTextures(0),
   55|  2.47k|        mTextures(nullptr),
   56|  2.47k|        mNumLights(0),
   57|  2.47k|        mLights(nullptr),
   58|  2.47k|        mNumCameras(0),
   59|  2.47k|        mCameras(nullptr),
   60|  2.47k|        mMetaData(nullptr),
   61|  2.47k|        mName(),
   62|  2.47k|        mNumSkeletons(0),
   63|  2.47k|        mSkeletons(nullptr),
   64|  2.47k|        mPrivate(new Assimp::ScenePrivateData()) {
   65|       |    // empty
   66|  2.47k|}
_ZN7aiSceneD2Ev:
   68|  2.47k|aiScene::~aiScene() {
   69|       |    // delete all sub-objects recursively
   70|  2.47k|    delete mRootNode;
   71|       |
   72|       |    // To make sure we won't crash if the data is invalid it's
   73|       |    // much better to check whether both mNumXXX and mXXX are
   74|       |    // valid instead of relying on just one of them.
   75|  2.47k|    if (mNumMeshes && mMeshes) {
  ------------------
  |  Branch (75:9): [True: 1.42k, False: 1.05k]
  |  Branch (75:23): [True: 1.42k, False: 0]
  ------------------
   76|  3.72k|        for (unsigned int a = 0; a < mNumMeshes; ++a) {
  ------------------
  |  Branch (76:34): [True: 2.29k, False: 1.42k]
  ------------------
   77|  2.29k|            delete mMeshes[a];
   78|  2.29k|        }
   79|  1.42k|    }
   80|  2.47k|    delete[] mMeshes;
   81|       |
   82|  2.47k|    if (mNumMaterials && mMaterials) {
  ------------------
  |  Branch (82:9): [True: 1.93k, False: 546]
  |  Branch (82:26): [True: 1.93k, False: 0]
  ------------------
   83|  4.19k|        for (unsigned int a = 0; a < mNumMaterials; ++a) {
  ------------------
  |  Branch (83:34): [True: 2.26k, False: 1.93k]
  ------------------
   84|  2.26k|            delete mMaterials[a];
   85|  2.26k|        }
   86|  1.93k|    }
   87|  2.47k|    delete[] mMaterials;
   88|       |
   89|  2.47k|    if (mNumAnimations && mAnimations) {
  ------------------
  |  Branch (89:9): [True: 0, False: 2.47k]
  |  Branch (89:27): [True: 0, False: 0]
  ------------------
   90|      0|        for (unsigned int a = 0; a < mNumAnimations; ++a) {
  ------------------
  |  Branch (90:34): [True: 0, False: 0]
  ------------------
   91|      0|            delete mAnimations[a];
   92|      0|        }
   93|      0|    }
   94|  2.47k|    delete[] mAnimations;
   95|       |
   96|  2.47k|    if (mNumTextures && mTextures) {
  ------------------
  |  Branch (96:9): [True: 47, False: 2.43k]
  |  Branch (96:25): [True: 47, False: 0]
  ------------------
   97|     94|        for (unsigned int a = 0; a < mNumTextures; ++a) {
  ------------------
  |  Branch (97:34): [True: 47, False: 47]
  ------------------
   98|     47|            delete mTextures[a];
   99|     47|        }
  100|     47|    }
  101|  2.47k|    delete[] mTextures;
  102|       |
  103|  2.47k|    if (mNumLights && mLights) {
  ------------------
  |  Branch (103:9): [True: 0, False: 2.47k]
  |  Branch (103:23): [True: 0, False: 0]
  ------------------
  104|      0|        for (unsigned int a = 0; a < mNumLights; ++a) {
  ------------------
  |  Branch (104:34): [True: 0, False: 0]
  ------------------
  105|      0|            delete mLights[a];
  106|      0|        }
  107|      0|    }
  108|  2.47k|    delete[] mLights;
  109|       |
  110|  2.47k|    if (mNumCameras && mCameras) {
  ------------------
  |  Branch (110:9): [True: 0, False: 2.47k]
  |  Branch (110:24): [True: 0, False: 0]
  ------------------
  111|      0|        for (unsigned int a = 0; a < mNumCameras; ++a) {
  ------------------
  |  Branch (111:34): [True: 0, False: 0]
  ------------------
  112|      0|            delete mCameras[a];
  113|      0|        }
  114|      0|    }
  115|  2.47k|    delete[] mCameras;
  116|       |
  117|  2.47k|    aiMetadata::Dealloc(mMetaData);
  118|       |
  119|  2.47k|    delete[] mSkeletons;
  120|       |
  121|  2.47k|    delete static_cast<Assimp::ScenePrivateData *>(mPrivate);
  122|  2.47k|}
_ZN6aiNodeC2ERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
  136|  8.39k|        mName(name),
  137|  8.39k|        mParent(nullptr),
  138|  8.39k|        mNumChildren(0),
  139|  8.39k|        mChildren(nullptr),
  140|  8.39k|        mNumMeshes(0),
  141|  8.39k|        mMeshes(nullptr),
  142|  8.39k|        mMetaData(nullptr) {
  143|       |    // empty
  144|  8.39k|}
_ZN6aiNodeD2Ev:
  147|  8.39k|aiNode::~aiNode() {
  148|       |    // delete all children recursively
  149|       |    // to make sure we won't crash if the data is invalid ...
  150|  8.39k|    if (mNumChildren && mChildren) {
  ------------------
  |  Branch (150:9): [True: 3.83k, False: 4.56k]
  |  Branch (150:25): [True: 3.83k, False: 0]
  ------------------
  151|  10.6k|        for (unsigned int a = 0; a < mNumChildren; a++)
  ------------------
  |  Branch (151:34): [True: 6.85k, False: 3.83k]
  ------------------
  152|  6.85k|            delete mChildren[a];
  153|  3.83k|    }
  154|  8.39k|    delete[] mChildren;
  155|  8.39k|    delete[] mMeshes;
  156|  8.39k|    delete mMetaData;
  157|  8.39k|}

_ZN6Assimp13GeometryUtils5heronEfff:
   49|  57.2k|ai_real GeometryUtils::heron( ai_real a, ai_real b, ai_real c ) {
   50|  57.2k|    const ai_real s    = (a + b + c) * 0.5;
   51|  57.2k|    const ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), static_cast<ai_real>(0.5));
   52|  57.2k|    return area;
   53|  57.2k|}
_ZN6Assimp13GeometryUtils10distance3DERK10aiVector3tIfES4_:
   56|   171k|ai_real GeometryUtils::distance3D( const aiVector3D &vA, const aiVector3D &vB ) {
   57|   171k|    const ai_real lx = ( vB.x - vA.x );
   58|   171k|    const ai_real ly = ( vB.y - vA.y );
   59|   171k|    const ai_real lz = ( vB.z - vA.z );
   60|   171k|    const ai_real a  = lx*lx + ly*ly + lz*lz;
   61|   171k|    const ai_real d  = pow( a, static_cast<ai_real>(0.5));
   62|       |
   63|   171k|    return d;
   64|   171k|}
_ZN6Assimp13GeometryUtils23calculateAreaOfTriangleERK6aiFaceP6aiMesh:
   67|  57.2k|ai_real GeometryUtils::calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) {
   68|  57.2k|    ai_real area = 0;
   69|  57.2k|    if (mesh == nullptr) {
  ------------------
  |  Branch (69:9): [True: 0, False: 57.2k]
  ------------------
   70|      0|        return area;
   71|      0|    }
   72|       |
   73|  57.2k|    const aiVector3D vA( mesh->mVertices[ face.mIndices[ 0 ] ] );
   74|  57.2k|    const aiVector3D vB( mesh->mVertices[ face.mIndices[ 1 ] ] );
   75|  57.2k|    const aiVector3D vC( mesh->mVertices[ face.mIndices[ 2 ] ] );
   76|       |
   77|  57.2k|    const ai_real a = distance3D( vA, vB );
   78|  57.2k|    const ai_real b = distance3D( vB, vC );
   79|  57.2k|    const ai_real c = distance3D( vC, vA );
   80|  57.2k|    area = heron( a, b, c );
   81|       |
   82|  57.2k|    return area;
   83|  57.2k|}

aiGetMaterialProperty:
   63|  5.10k|        const aiMaterialProperty **pPropOut) {
   64|  5.10k|    ai_assert(pMat != nullptr);
   65|  5.10k|    ai_assert(pKey != nullptr);
   66|  5.10k|    ai_assert(pPropOut != nullptr);
   67|       |
   68|       |    /*  Just search for a property with exactly this name ..
   69|       |     *  could be improved by hashing, but it's possibly
   70|       |     *  no worth the effort (we're bound to C structures,
   71|       |     *  thus std::map or derivates are not applicable. */
   72|  51.3k|    for (unsigned int i = 0; i < pMat->mNumProperties; ++i) {
  ------------------
  |  Branch (72:30): [True: 51.3k, False: 0]
  ------------------
   73|  51.3k|        aiMaterialProperty *prop = pMat->mProperties[i];
   74|       |
   75|  51.3k|        if (prop /* just for safety ... */
  ------------------
  |  Branch (75:13): [True: 51.3k, False: 0]
  ------------------
   76|  51.3k|                && 0 == strncmp(prop->mKey.data, pKey, strlen(pKey)) && (UINT_MAX == type || prop->mSemantic == type) /* UINT_MAX is a wild-card, but this is undocumented :-) */
  ------------------
  |  Branch (76:20): [True: 5.10k, False: 46.2k]
  |  Branch (76:74): [True: 0, False: 5.10k]
  |  Branch (76:94): [True: 5.10k, False: 0]
  ------------------
   77|  5.10k|                && (UINT_MAX == index || prop->mIndex == index)) {
  ------------------
  |  Branch (77:21): [True: 0, False: 5.10k]
  |  Branch (77:42): [True: 5.10k, False: 0]
  ------------------
   78|  5.10k|            *pPropOut = pMat->mProperties[i];
   79|  5.10k|            return AI_SUCCESS;
   80|  5.10k|        }
   81|  51.3k|    }
   82|      0|    *pPropOut = nullptr;
   83|       |
   84|       |    return AI_FAILURE;
   85|  5.10k|}
aiGetMaterialFloatArray:
  194|  2.55k|        unsigned int *pMax) {
  195|  2.55k|    return GetMaterialFloatArray(pMat, pKey, type, index, pOut, pMax);
  196|  2.55k|}
aiGetMaterialIntegerArray:
  205|  2.55k|        unsigned int *pMax) {
  206|  2.55k|    ai_assert(pOut != nullptr);
  207|  2.55k|    ai_assert(pMat != nullptr);
  208|       |
  209|  2.55k|    const aiMaterialProperty *prop;
  210|  2.55k|    aiGetMaterialProperty(pMat, pKey, type, index, &prop);
  211|  2.55k|    if (!prop) {
  ------------------
  |  Branch (211:9): [True: 0, False: 2.55k]
  ------------------
  212|      0|        return AI_FAILURE;
  213|      0|    }
  214|       |
  215|       |    // data is given in ints, simply copy it
  216|  2.55k|    unsigned int iWrite = 0;
  217|  2.55k|    if (aiPTI_Integer == prop->mType || aiPTI_Buffer == prop->mType) {
  ------------------
  |  Branch (217:9): [True: 0, False: 2.55k]
  |  Branch (217:41): [True: 2.55k, False: 0]
  ------------------
  218|  2.55k|        iWrite = std::max(static_cast<unsigned int>(prop->mDataLength / sizeof(int32_t)), 1u);
  219|  2.55k|        if (pMax) {
  ------------------
  |  Branch (219:13): [True: 0, False: 2.55k]
  ------------------
  220|      0|            iWrite = std::min(*pMax, iWrite);
  221|      0|        }
  222|  2.55k|        if (1 == prop->mDataLength) {
  ------------------
  |  Branch (222:13): [True: 0, False: 2.55k]
  ------------------
  223|       |            // bool type, 1 byte
  224|      0|            *pOut = static_cast<int>(*prop->mData);
  225|  2.55k|        } else {
  226|  5.10k|            for (unsigned int a = 0; a < iWrite; ++a) {
  ------------------
  |  Branch (226:38): [True: 2.55k, False: 2.55k]
  ------------------
  227|  2.55k|                pOut[a] = static_cast<int>(reinterpret_cast<int32_t *>(prop->mData)[a]);
  228|  2.55k|            }
  229|  2.55k|        }
  230|  2.55k|        if (pMax) {
  ------------------
  |  Branch (230:13): [True: 0, False: 2.55k]
  ------------------
  231|      0|            *pMax = iWrite;
  232|      0|        }
  233|  2.55k|    }
  234|       |    // data is given in floats convert to int
  235|      0|    else if (aiPTI_Float == prop->mType) {
  ------------------
  |  Branch (235:14): [True: 0, False: 0]
  ------------------
  236|      0|        iWrite = prop->mDataLength / sizeof(float);
  237|      0|        if (pMax) {
  ------------------
  |  Branch (237:13): [True: 0, False: 0]
  ------------------
  238|      0|            iWrite = std::min(*pMax, iWrite);
  239|      0|            ;
  240|      0|        }
  241|      0|        for (unsigned int a = 0; a < iWrite; ++a) {
  ------------------
  |  Branch (241:34): [True: 0, False: 0]
  ------------------
  242|      0|            pOut[a] = static_cast<int>(reinterpret_cast<float *>(prop->mData)[a]);
  243|      0|        }
  244|      0|        if (pMax) {
  ------------------
  |  Branch (244:13): [True: 0, False: 0]
  ------------------
  245|      0|            *pMax = iWrite;
  246|      0|        }
  247|      0|    }
  248|       |    // it is a string ... no way to read something out of this
  249|      0|    else {
  250|      0|        if (pMax) {
  ------------------
  |  Branch (250:13): [True: 0, False: 0]
  ------------------
  251|      0|            iWrite = *pMax;
  252|      0|        }
  253|       |        // strings are zero-terminated with a 32 bit length prefix, so this is safe
  254|      0|        const char *cur = prop->mData + 4;
  255|      0|        ai_assert(prop->mDataLength >= 5);
  256|      0|        ai_assert(!prop->mData[prop->mDataLength - 1]);
  257|      0|        for (unsigned int a = 0;; ++a) {
  258|      0|            pOut[a] = strtol10(cur, &cur);
  259|      0|            if (a == iWrite - 1) {
  ------------------
  |  Branch (259:17): [True: 0, False: 0]
  ------------------
  260|      0|                break;
  261|      0|            }
  262|      0|            if (!IsSpace(*cur)) {
  ------------------
  |  Branch (262:17): [True: 0, False: 0]
  ------------------
  263|      0|                ASSIMP_LOG_ERROR("Material property", pKey,
  264|      0|                                 " is a string; failed to parse an integer array out of it.");
  265|      0|                return AI_FAILURE;
  266|      0|            }
  267|      0|        }
  268|       |
  269|      0|        if (pMax) {
  ------------------
  |  Branch (269:13): [True: 0, False: 0]
  ------------------
  270|      0|            *pMax = iWrite;
  271|      0|        }
  272|      0|    }
  273|  2.55k|    return AI_SUCCESS;
  274|  2.55k|}
_ZN10aiMaterialC2Ev:
  418|  3.49k|aiMaterial::aiMaterial() : mProperties(nullptr), mNumProperties(0), mNumAllocated(DefaultNumAllocated) {
  419|       |    // Allocate 5 entries by default
  420|  3.49k|    mProperties = new aiMaterialProperty *[DefaultNumAllocated];
  421|  3.49k|}
_ZN10aiMaterialD2Ev:
  424|  3.49k|aiMaterial::~aiMaterial() {
  425|  3.49k|    Clear();
  426|       |
  427|  3.49k|    delete[] mProperties;
  428|  3.49k|}
_ZN10aiMaterial5ClearEv:
  439|  3.49k|void aiMaterial::Clear() {
  440|  42.9k|    for (unsigned int i = 0; i < mNumProperties; ++i) {
  ------------------
  |  Branch (440:30): [True: 39.4k, False: 3.49k]
  ------------------
  441|       |        // delete this entry
  442|  39.4k|        delete mProperties[i];
  443|  39.4k|        AI_DEBUG_INVALIDATE_PTR(mProperties[i]);
  444|  39.4k|    }
  445|  3.49k|    mNumProperties = 0;
  446|       |
  447|       |    // The array remains allocated, we just invalidated its contents
  448|  3.49k|}
_ZN10aiMaterial17AddBinaryPropertyEPKvjPKcjj18aiPropertyTypeInfo:
  480|  39.4k|        aiPropertyTypeInfo pType) {
  481|  39.4k|    ai_assert(pInput != nullptr);
  482|  39.4k|    ai_assert(pKey != nullptr);
  483|  39.4k|    ai_assert(0 != pSizeInBytes);
  484|       |
  485|  39.4k|    if (0 == pSizeInBytes) {
  ------------------
  |  Branch (485:9): [True: 0, False: 39.4k]
  ------------------
  486|      0|        return AI_FAILURE;
  487|      0|    }
  488|       |
  489|       |    // first search the list whether there is already an entry with this key
  490|  39.4k|    unsigned int iOutIndex(UINT_MAX);
  491|   253k|    for (unsigned int i = 0; i < mNumProperties; ++i) {
  ------------------
  |  Branch (491:30): [True: 213k, False: 39.4k]
  ------------------
  492|   213k|        aiMaterialProperty *prop(mProperties[i]);
  493|       |
  494|   213k|        if (prop /* just for safety */ && !strcmp(prop->mKey.data, pKey) &&
  ------------------
  |  Branch (494:13): [True: 213k, False: 0]
  |  Branch (494:43): [True: 325, False: 213k]
  ------------------
  495|    325|                prop->mSemantic == type && prop->mIndex == index) {
  ------------------
  |  Branch (495:17): [True: 0, False: 325]
  |  Branch (495:44): [True: 0, False: 0]
  ------------------
  496|       |
  497|      0|            delete mProperties[i];
  498|      0|            iOutIndex = i;
  499|      0|        }
  500|   213k|    }
  501|       |
  502|       |    // Allocate a new material property
  503|  39.4k|    auto pcNew = std::make_unique<aiMaterialProperty>();
  504|       |
  505|       |    // .. and fill it
  506|  39.4k|    pcNew->mType = pType;
  507|  39.4k|    pcNew->mSemantic = type;
  508|  39.4k|    pcNew->mIndex = index;
  509|       |
  510|  39.4k|    pcNew->mDataLength = pSizeInBytes;
  511|  39.4k|    pcNew->mData = new char[pSizeInBytes];
  512|  39.4k|    memcpy(pcNew->mData, pInput, pSizeInBytes);
  513|       |
  514|  39.4k|    const size_t keyLen = ::strlen(pKey);
  515|  39.4k|    pcNew->mKey.length = static_cast<ai_uint32>(std::min<size_t>(keyLen, AI_MAXLEN - 1));
  516|  39.4k|    if (keyLen >= AI_MAXLEN) {
  ------------------
  |  Branch (516:9): [True: 0, False: 39.4k]
  ------------------
  517|      0|        ASSIMP_LOG_WARN("aiMaterial: property key '", pKey, "' exceeds AI_MAXLEN and will be truncated.");
  518|      0|    }
  519|  39.4k|	memcpy(pcNew->mKey.data, pKey, pcNew->mKey.length);
  520|  39.4k|    pcNew->mKey.data[pcNew->mKey.length] = '\0';
  521|       |
  522|  39.4k|    if (UINT_MAX != iOutIndex) {
  ------------------
  |  Branch (522:9): [True: 0, False: 39.4k]
  ------------------
  523|      0|        mProperties[iOutIndex] = pcNew.release();
  524|      0|        return AI_SUCCESS;
  525|      0|    }
  526|       |
  527|       |    // resize the array ... double the storage allocated
  528|  39.4k|    if (mNumProperties == mNumAllocated) {
  ------------------
  |  Branch (528:9): [True: 6.84k, False: 32.5k]
  ------------------
  529|  6.84k|        const unsigned int iOld = mNumAllocated;
  530|  6.84k|        mNumAllocated *= 2;
  531|       |
  532|  6.84k|        aiMaterialProperty **ppTemp;
  533|  6.84k|        try {
  534|  6.84k|            ppTemp = new aiMaterialProperty *[mNumAllocated];
  535|  6.84k|        } catch (std::bad_alloc &) {
  536|      0|            return AI_OUTOFMEMORY;
  537|      0|        }
  538|       |
  539|       |        // just copy all items over; then replace the old array
  540|  6.84k|        memcpy(ppTemp, mProperties, iOld * sizeof(void *));
  541|       |
  542|  6.84k|        delete[] mProperties;
  543|  6.84k|        mProperties = ppTemp;
  544|  6.84k|    }
  545|       |    // push back ...
  546|  39.4k|    mProperties[mNumProperties++] = pcNew.release();
  547|       |
  548|       |    return AI_SUCCESS;
  549|  39.4k|}
_ZN10aiMaterial11AddPropertyEPK8aiStringPKcjj:
  555|  5.02k|        unsigned int index) {
  556|       |    ai_assert(sizeof(ai_uint32) == 4);
  557|  5.02k|    return AddBinaryProperty(pInput,
  558|  5.02k|            static_cast<unsigned int>(pInput->length + 1 + 4),
  559|  5.02k|            pKey,
  560|  5.02k|            type,
  561|  5.02k|            index,
  562|  5.02k|            aiPTI_String);
  563|  5.02k|}
_ZN6Assimp19ComputeMaterialHashEPK10aiMaterialb:
  566|  1.32k|uint32_t Assimp::ComputeMaterialHash(const aiMaterial *mat, bool includeMatName /*= false*/) {
  567|  1.32k|    uint32_t hash = 1503; // magic start value, chosen to be my birthday :-)
  568|  17.3k|    for (unsigned int i = 0; i < mat->mNumProperties; ++i) {
  ------------------
  |  Branch (568:30): [True: 16.0k, False: 1.32k]
  ------------------
  569|       |        // Exclude all properties whose first character is '?' from the hash
  570|       |        // See doc for aiMaterialProperty.
  571|  16.0k|        const aiMaterialProperty *prop = mat->mProperties[i];
  572|  16.0k|        if (nullptr != prop && (includeMatName || prop->mKey.data[0] != '?')) {
  ------------------
  |  Branch (572:13): [True: 16.0k, False: 0]
  |  Branch (572:33): [True: 0, False: 16.0k]
  |  Branch (572:51): [True: 14.9k, False: 1.03k]
  ------------------
  573|       |
  574|  14.9k|            hash = SuperFastHash(prop->mKey.data, (unsigned int)prop->mKey.length, hash);
  575|  14.9k|            hash = SuperFastHash(prop->mData, prop->mDataLength, hash);
  576|       |
  577|       |            // Combine the semantic and the index with the hash
  578|  14.9k|            hash = SuperFastHash((const char *)&prop->mSemantic, sizeof(unsigned int), hash);
  579|  14.9k|            hash = SuperFastHash((const char *)&prop->mIndex, sizeof(unsigned int), hash);
  580|  14.9k|        }
  581|  16.0k|    }
  582|  1.32k|    return hash;
  583|  1.32k|}
MaterialSystem.cpp:_ZN12_GLOBAL__N_121GetMaterialFloatArrayIfEE8aiReturnPK10aiMaterialPKcjjPT_Pj:
   97|  2.55k|        unsigned int *pMax) {
   98|  2.55k|    ai_assert(pOut != nullptr);
   99|  2.55k|    ai_assert(pMat != nullptr);
  100|       |
  101|  2.55k|    const aiMaterialProperty *prop{nullptr};
  102|  2.55k|    aiGetMaterialProperty(pMat, pKey, type, index, &prop);
  103|  2.55k|    if (nullptr == prop) {
  ------------------
  |  Branch (103:9): [True: 0, False: 2.55k]
  ------------------
  104|      0|        return AI_FAILURE;
  105|      0|    }
  106|       |
  107|       |    // data is given in floats, convert to TReal
  108|  2.55k|    unsigned int iWrite = 0;
  109|  2.55k|    if (aiPTI_Float == prop->mType || aiPTI_Buffer == prop->mType) {
  ------------------
  |  Branch (109:9): [True: 2.55k, False: 0]
  |  Branch (109:39): [True: 0, False: 0]
  ------------------
  110|  2.55k|        iWrite = prop->mDataLength / sizeof(float);
  111|  2.55k|        if (pMax) {
  ------------------
  |  Branch (111:13): [True: 0, False: 2.55k]
  ------------------
  112|      0|            iWrite = std::min(*pMax, iWrite);
  113|      0|        }
  114|       |
  115|  5.10k|        for (unsigned int a = 0; a < iWrite; ++a) {
  ------------------
  |  Branch (115:34): [True: 2.55k, False: 2.55k]
  ------------------
  116|  2.55k|            pOut[a] = static_cast<TReal>(reinterpret_cast<float *>(prop->mData)[a]);
  117|  2.55k|        }
  118|       |
  119|  2.55k|        if (pMax) {
  ------------------
  |  Branch (119:13): [True: 0, False: 2.55k]
  ------------------
  120|      0|            *pMax = iWrite;
  121|      0|        }
  122|  2.55k|    } else if (aiPTI_Double == prop->mType) { // data is given in doubles, convert to TReal
  ------------------
  |  Branch (122:16): [True: 0, False: 0]
  ------------------
  123|      0|        iWrite = prop->mDataLength / sizeof(double);
  124|      0|        if (pMax) {
  ------------------
  |  Branch (124:13): [True: 0, False: 0]
  ------------------
  125|      0|            iWrite = std::min(*pMax, iWrite);
  126|      0|            ;
  127|      0|        }
  128|      0|        for (unsigned int a = 0; a < iWrite; ++a) {
  ------------------
  |  Branch (128:34): [True: 0, False: 0]
  ------------------
  129|      0|            pOut[a] = static_cast<TReal>(reinterpret_cast<double *>(prop->mData)[a]);
  130|      0|        }
  131|      0|        if (pMax) {
  ------------------
  |  Branch (131:13): [True: 0, False: 0]
  ------------------
  132|      0|            *pMax = iWrite;
  133|      0|        }
  134|      0|    } else if (aiPTI_Integer == prop->mType) { // data is given in ints, convert to TReal
  ------------------
  |  Branch (134:16): [True: 0, False: 0]
  ------------------
  135|      0|        iWrite = prop->mDataLength / sizeof(int32_t);
  136|      0|        if (pMax) {
  ------------------
  |  Branch (136:13): [True: 0, False: 0]
  ------------------
  137|      0|            iWrite = std::min(*pMax, iWrite);
  138|      0|            ;
  139|      0|        }
  140|      0|        for (unsigned int a = 0; a < iWrite; ++a) {
  ------------------
  |  Branch (140:34): [True: 0, False: 0]
  ------------------
  141|      0|            pOut[a] = static_cast<TReal>(reinterpret_cast<int32_t *>(prop->mData)[a]);
  142|      0|        }
  143|      0|        if (pMax) {
  ------------------
  |  Branch (143:13): [True: 0, False: 0]
  ------------------
  144|      0|            *pMax = iWrite;
  145|      0|        }
  146|      0|    } else { // a string ... read floats separated by spaces
  147|      0|        if (pMax) {
  ------------------
  |  Branch (147:13): [True: 0, False: 0]
  ------------------
  148|      0|            iWrite = *pMax;
  149|      0|        }
  150|       |        // strings are zero-terminated with a 32 bit length prefix, so this is safe
  151|      0|        const char *cur = prop->mData + 4;
  152|      0|        ai_assert(prop->mDataLength >= 5);
  153|      0|        ai_assert(!prop->mData[prop->mDataLength - 1]);
  154|      0|        for (unsigned int a = 0;; ++a) {
  155|      0|            cur = fast_atoreal_move(cur, pOut[a]);
  156|      0|            if (a == iWrite - 1) {
  ------------------
  |  Branch (156:17): [True: 0, False: 0]
  ------------------
  157|      0|                break;
  158|      0|            }
  159|      0|            if (!IsSpace(*cur)) {
  ------------------
  |  Branch (159:17): [True: 0, False: 0]
  ------------------
  160|      0|                ASSIMP_LOG_ERROR("Material property", pKey,
  161|      0|                                 " is a string; failed to parse a float array out of it.");
  162|      0|                return AI_FAILURE;
  163|      0|            }
  164|      0|        }
  165|       |
  166|      0|        if (pMax) {
  ------------------
  |  Branch (166:13): [True: 0, False: 0]
  ------------------
  167|      0|            *pMax = iWrite;
  168|      0|        }
  169|      0|    }
  170|       |
  171|  2.55k|    return AI_SUCCESS;
  172|  2.55k|}

_ZNK6Assimp16ArmaturePopulate8IsActiveEj:
   59|  1.48k|bool ArmaturePopulate::IsActive(unsigned int pFlags) const {
   60|  1.48k|    return (pFlags & aiProcess_PopulateArmatureData) != 0;
   61|  1.48k|}

_ZN6Assimp16ArmaturePopulateC2Ev:
   71|  3.48k|    ArmaturePopulate() = default;

_ZN6Assimp19CalcTangentsProcessC2Ev:
   59|  3.48k|        configMaxAngle(float(AI_DEG_TO_RAD(45.f))), configSourceUV(0) {
   60|       |    // nothing to do here
   61|  3.48k|}
_ZNK6Assimp19CalcTangentsProcess8IsActiveEj:
   65|  1.43k|bool CalcTangentsProcess::IsActive(unsigned int pFlags) const {
   66|  1.43k|    return (pFlags & aiProcess_CalcTangentSpace) != 0;
   67|  1.43k|}
_ZN6Assimp19CalcTangentsProcess15SetupPropertiesEPKNS_8ImporterE:
   71|  1.43k|void CalcTangentsProcess::SetupProperties(const Importer *pImp) {
   72|  1.43k|    ai_assert(nullptr != pImp);
   73|       |
   74|       |    // get the current value of the property
   75|  1.43k|    configMaxAngle = pImp->GetPropertyFloat(AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE, 45.f);
   76|  1.43k|    configMaxAngle = std::max(std::min(configMaxAngle, 45.0f), 0.0f);
   77|  1.43k|    configMaxAngle = AI_DEG_TO_RAD(configMaxAngle);
   78|       |
   79|       |    configSourceUV = pImp->GetPropertyInteger(AI_CONFIG_PP_CT_TEXTURE_CHANNEL_INDEX, 0);
   80|  1.43k|}
_ZN6Assimp19CalcTangentsProcess7ExecuteEP7aiScene:
   84|  1.43k|void CalcTangentsProcess::Execute(aiScene *pScene) {
   85|  1.43k|    ai_assert(nullptr != pScene);
   86|       |
   87|  1.43k|    ASSIMP_LOG_DEBUG("CalcTangentsProcess begin");
   88|       |
   89|  1.43k|    bool bHas = false;
   90|  3.54k|    for (unsigned int a = 0; a < pScene->mNumMeshes; a++) {
  ------------------
  |  Branch (90:30): [True: 2.11k, False: 1.43k]
  ------------------
   91|  2.11k|        if (ProcessMesh(pScene->mMeshes[a], a)) bHas = true;
  ------------------
  |  Branch (91:13): [True: 231, False: 1.88k]
  ------------------
   92|  2.11k|    }
   93|       |
   94|  1.43k|    if (bHas) {
  ------------------
  |  Branch (94:9): [True: 231, False: 1.20k]
  ------------------
   95|    231|        ASSIMP_LOG_INFO("CalcTangentsProcess finished. Tangents have been calculated");
   96|  1.20k|    } else {
   97|       |        ASSIMP_LOG_DEBUG("CalcTangentsProcess finished");
   98|  1.20k|    }
   99|  1.43k|}
_ZN6Assimp19CalcTangentsProcess11ProcessMeshEP6aiMeshj:
  103|  2.11k|bool CalcTangentsProcess::ProcessMesh(aiMesh *pMesh, unsigned int meshIndex) {
  104|       |    // we assume that the mesh is still in the verbose vertex format where each face has its own set
  105|       |    // of vertices and no vertices are shared between faces. Sadly I don't know any quick test to
  106|       |    // assert() it here.
  107|       |    // assert( must be verbose, dammit);
  108|       |
  109|  2.11k|    if (pMesh->mTangents) // this implies that mBitangents is also there
  ------------------
  |  Branch (109:9): [True: 33, False: 2.08k]
  ------------------
  110|     33|        return false;
  111|       |
  112|       |    // If the mesh consists of lines and/or points but not of
  113|       |    // triangles or higher-order polygons the normal vectors
  114|       |    // are undefined.
  115|  2.08k|    if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON))) {
  ------------------
  |  Branch (115:9): [True: 1.29k, False: 793]
  ------------------
  116|  1.29k|        ASSIMP_LOG_INFO("Tangents are undefined for line and point meshes");
  117|  1.29k|        return false;
  118|  1.29k|    }
  119|       |
  120|       |    // what we can check, though, is if the mesh has normals and texture coordinates. That's a requirement
  121|    793|    if (pMesh->mNormals == nullptr) {
  ------------------
  |  Branch (121:9): [True: 0, False: 793]
  ------------------
  122|      0|        ASSIMP_LOG_ERROR("Failed to compute tangents; need normals");
  123|      0|        return false;
  124|      0|    }
  125|    793|    if (configSourceUV >= AI_MAX_NUMBER_OF_TEXTURECOORDS || !pMesh->mTextureCoords[configSourceUV]) {
  ------------------
  |  Branch (125:9): [True: 0, False: 793]
  |  Branch (125:61): [True: 562, False: 231]
  ------------------
  126|    562|        ASSIMP_LOG_ERROR("Failed to compute tangents; need UV data in channel", configSourceUV);
  127|    562|        return false;
  128|    562|    }
  129|       |
  130|    231|    const float angleEpsilon = 0.9999f;
  131|       |
  132|    231|    std::vector<bool> vertexDone(pMesh->mNumVertices, false);
  133|    231|    const float qnan = get_qnan();
  134|       |
  135|       |    // create space for the tangents and bitangents
  136|    231|    pMesh->mTangents = new aiVector3D[pMesh->mNumVertices];
  137|    231|    pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices];
  138|       |
  139|    231|    const aiVector3D *meshPos = pMesh->mVertices;
  140|    231|    const aiVector3D *meshNorm = pMesh->mNormals;
  141|    231|    const aiVector3D *meshTex = pMesh->mTextureCoords[configSourceUV];
  142|    231|    aiVector3D *meshTang = pMesh->mTangents;
  143|    231|    aiVector3D *meshBitang = pMesh->mBitangents;
  144|       |
  145|       |    // calculate the tangent and bitangent for every face
  146|  2.02k|    for (unsigned int a = 0; a < pMesh->mNumFaces; a++) {
  ------------------
  |  Branch (146:30): [True: 1.79k, False: 231]
  ------------------
  147|  1.79k|        const aiFace &face = pMesh->mFaces[a];
  148|  1.79k|        if (face.mNumIndices < 3) {
  ------------------
  |  Branch (148:13): [True: 0, False: 1.79k]
  ------------------
  149|       |            // There are less than three indices, thus the tangent vector
  150|       |            // is not defined. We are finished with these vertices now,
  151|       |            // their tangent vectors are set to qnan.
  152|      0|            for (unsigned int i = 0; i < face.mNumIndices; ++i) {
  ------------------
  |  Branch (152:38): [True: 0, False: 0]
  ------------------
  153|      0|                unsigned int idx = face.mIndices[i];
  154|      0|                vertexDone[idx] = true;
  155|      0|                meshTang[idx] = aiVector3D(qnan);
  156|      0|                meshBitang[idx] = aiVector3D(qnan);
  157|      0|            }
  158|       |
  159|      0|            continue;
  160|      0|        }
  161|       |
  162|       |        // triangle or polygon... we always use only the first three indices. A polygon
  163|       |        // is supposed to be planar anyways....
  164|       |        // FIXME: (thom) create correct calculation for multi-vertex polygons maybe?
  165|  1.79k|        const unsigned int p0 = face.mIndices[0], p1 = face.mIndices[1], p2 = face.mIndices[2];
  166|       |
  167|       |        // position differences p1->p2 and p1->p3
  168|  1.79k|        aiVector3D v = meshPos[p1] - meshPos[p0], w = meshPos[p2] - meshPos[p0];
  169|       |
  170|       |        // texture offset p1->p2 and p1->p3
  171|  1.79k|        float sx = meshTex[p1].x - meshTex[p0].x, sy = meshTex[p1].y - meshTex[p0].y;
  172|  1.79k|        float tx = meshTex[p2].x - meshTex[p0].x, ty = meshTex[p2].y - meshTex[p0].y;
  173|  1.79k|        float dirCorrection = (tx * sy - ty * sx) < 0.0f ? -1.0f : 1.0f;
  ------------------
  |  Branch (173:31): [True: 443, False: 1.35k]
  ------------------
  174|       |        // when t1, t2, t3 in same position in UV space, just use default UV direction.
  175|  1.79k|        if (sx * ty == sy * tx) {
  ------------------
  |  Branch (175:13): [True: 931, False: 864]
  ------------------
  176|    931|            sx = 0.0;
  177|    931|            sy = 1.0;
  178|    931|            tx = 1.0;
  179|    931|            ty = 0.0;
  180|    931|        }
  181|       |
  182|       |        // tangent points in the direction where to positive X axis of the texture coord's would point in model space
  183|       |        // bitangent's points along the positive Y axis of the texture coord's, respectively
  184|  1.79k|        aiVector3D tangent, bitangent;
  185|  1.79k|        tangent.x = (w.x * sy - v.x * ty) * dirCorrection;
  186|  1.79k|        tangent.y = (w.y * sy - v.y * ty) * dirCorrection;
  187|  1.79k|        tangent.z = (w.z * sy - v.z * ty) * dirCorrection;
  188|  1.79k|        bitangent.x = (w.x * sx - v.x * tx) * dirCorrection;
  189|  1.79k|        bitangent.y = (w.y * sx - v.y * tx) * dirCorrection;
  190|  1.79k|        bitangent.z = (w.z * sx - v.z * tx) * dirCorrection;
  191|       |
  192|       |        // store for every vertex of that face
  193|  7.18k|        for (unsigned int b = 0; b < face.mNumIndices; ++b) {
  ------------------
  |  Branch (193:34): [True: 5.38k, False: 1.79k]
  ------------------
  194|  5.38k|            unsigned int p = face.mIndices[b];
  195|       |
  196|       |            // project tangent and bitangent into the plane formed by the vertex' normal
  197|  5.38k|            aiVector3D localTangent = tangent - meshNorm[p] * (tangent * meshNorm[p]);
  198|  5.38k|            aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]);
  199|  5.38k|            localTangent.NormalizeSafe();
  200|  5.38k|            localBitangent.NormalizeSafe();
  201|       |
  202|       |            // reconstruct tangent/bitangent according to normal and bitangent/tangent when it's infinite or NaN.
  203|  5.38k|            bool invalid_tangent = is_special_float(localTangent.x) || is_special_float(localTangent.y) || is_special_float(localTangent.z)
  ------------------
  |  Branch (203:36): [True: 1.49k, False: 3.88k]
  |  Branch (203:72): [True: 59, False: 3.82k]
  |  Branch (203:108): [True: 43, False: 3.78k]
  ------------------
  204|  3.78k|                || (-0.5f < localTangent.x && localTangent.x < 0.5f && -0.5f < localTangent.y && localTangent.y < 0.5f && -0.5f < localTangent.z && localTangent.z < 0.5f);
  ------------------
  |  Branch (204:21): [True: 3.45k, False: 330]
  |  Branch (204:47): [True: 2.76k, False: 693]
  |  Branch (204:72): [True: 2.54k, False: 212]
  |  Branch (204:98): [True: 2.15k, False: 395]
  |  Branch (204:123): [True: 1.84k, False: 305]
  |  Branch (204:149): [True: 1.71k, False: 130]
  ------------------
  205|  5.38k|            bool invalid_bitangent = is_special_float(localBitangent.x) || is_special_float(localBitangent.y) || is_special_float(localBitangent.z)
  ------------------
  |  Branch (205:38): [True: 1.38k, False: 4.00k]
  |  Branch (205:76): [True: 69, False: 3.93k]
  |  Branch (205:114): [True: 41, False: 3.89k]
  ------------------
  206|  3.89k|                || (-0.5f < localBitangent.x && localBitangent.x < 0.5f && -0.5f < localBitangent.y && localBitangent.y < 0.5f && -0.5f < localBitangent.z && localBitangent.z < 0.5f);
  ------------------
  |  Branch (206:21): [True: 3.47k, False: 413]
  |  Branch (206:49): [True: 3.08k, False: 391]
  |  Branch (206:76): [True: 2.51k, False: 574]
  |  Branch (206:104): [True: 2.09k, False: 420]
  |  Branch (206:131): [True: 1.83k, False: 257]
  |  Branch (206:159): [True: 1.46k, False: 375]
  ------------------
  207|  5.38k|            if (invalid_tangent != invalid_bitangent) {
  ------------------
  |  Branch (207:17): [True: 1.26k, False: 4.12k]
  ------------------
  208|  1.26k|                if (invalid_tangent) {
  ------------------
  |  Branch (208:21): [True: 815, False: 450]
  ------------------
  209|    815|                    localTangent = meshNorm[p] ^ localBitangent;
  210|    815|                    localTangent.NormalizeSafe();
  211|    815|                } else {
  212|    450|                    localBitangent = localTangent ^ meshNorm[p];
  213|    450|                    localBitangent.NormalizeSafe();
  214|    450|                }
  215|  1.26k|            }
  216|       |
  217|       |            // and write it into the mesh.
  218|  5.38k|            meshTang[p] = localTangent;
  219|  5.38k|            meshBitang[p] = localBitangent;
  220|  5.38k|        }
  221|  1.79k|    }
  222|       |
  223|       |    // create a helper to quickly find locally close vertices among the vertex array
  224|       |    // FIX: check whether we can reuse the SpatialSort of a previous step
  225|    231|    SpatialSort *vertexFinder = nullptr;
  226|    231|    SpatialSort _vertexFinder;
  227|    231|    float posEpsilon = 10e-6f;
  228|    231|    if (shared) {
  ------------------
  |  Branch (228:9): [True: 231, False: 0]
  ------------------
  229|    231|        std::vector<std::pair<SpatialSort, float>> *avf;
  230|    231|        shared->GetProperty(AI_SPP_SPATIAL_SORT, avf);
  ------------------
  |  |  166|    231|#define AI_SPP_SPATIAL_SORT "$Spat"
  ------------------
  231|    231|        if (avf) {
  ------------------
  |  Branch (231:13): [True: 231, False: 0]
  ------------------
  232|    231|            std::pair<SpatialSort, float> &blubb = avf->operator[](meshIndex);
  233|    231|            vertexFinder = &blubb.first;
  234|    231|            posEpsilon = blubb.second;
  235|    231|            ;
  236|    231|        }
  237|    231|    }
  238|    231|    if (!vertexFinder) {
  ------------------
  |  Branch (238:9): [True: 0, False: 231]
  ------------------
  239|      0|        _vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof(aiVector3D));
  240|      0|        vertexFinder = &_vertexFinder;
  241|      0|        posEpsilon = ComputePositionEpsilon(pMesh);
  242|      0|    }
  243|    231|    std::vector<unsigned int> verticesFound;
  244|       |
  245|    231|    const float fLimit = std::cos(configMaxAngle);
  246|    231|    std::vector<unsigned int> closeVertices;
  247|       |
  248|       |    // in the second pass we now smooth out all tangents and bitangents at the same local position
  249|       |    // if they are not too far off.
  250|  5.23k|    for (unsigned int a = 0; a < pMesh->mNumVertices; a++) {
  ------------------
  |  Branch (250:30): [True: 5.00k, False: 231]
  ------------------
  251|  5.00k|        if (vertexDone[a])
  ------------------
  |  Branch (251:13): [True: 1.67k, False: 3.33k]
  ------------------
  252|  1.67k|            continue;
  253|       |
  254|  3.33k|        const aiVector3D &origPos = pMesh->mVertices[a];
  255|  3.33k|        const aiVector3D &origNorm = pMesh->mNormals[a];
  256|  3.33k|        const aiVector3D &origTang = pMesh->mTangents[a];
  257|  3.33k|        const aiVector3D &origBitang = pMesh->mBitangents[a];
  258|  3.33k|        closeVertices.resize(0);
  259|       |
  260|       |        // find all vertices close to that position
  261|  3.33k|        vertexFinder->FindPositions(origPos, posEpsilon, verticesFound);
  262|       |
  263|  3.33k|        closeVertices.reserve(verticesFound.size() + 5);
  264|  3.33k|        closeVertices.push_back(a);
  265|       |
  266|       |        // look among them for other vertices sharing the same normal and a close-enough tangent/bitangent
  267|  52.4k|        for (unsigned int b = 0; b < verticesFound.size(); b++) {
  ------------------
  |  Branch (267:34): [True: 49.1k, False: 3.33k]
  ------------------
  268|  49.1k|            unsigned int idx = verticesFound[b];
  269|  49.1k|            if (vertexDone[idx])
  ------------------
  |  Branch (269:17): [True: 5.84k, False: 43.2k]
  ------------------
  270|  5.84k|                continue;
  271|  43.2k|            if (meshNorm[idx] * origNorm < angleEpsilon)
  ------------------
  |  Branch (271:17): [True: 35.7k, False: 7.57k]
  ------------------
  272|  35.7k|                continue;
  273|  7.57k|            if (meshTang[idx] * origTang < fLimit)
  ------------------
  |  Branch (273:17): [True: 4.30k, False: 3.26k]
  ------------------
  274|  4.30k|                continue;
  275|  3.26k|            if (meshBitang[idx] * origBitang < fLimit)
  ------------------
  |  Branch (275:17): [True: 685, False: 2.57k]
  ------------------
  276|    685|                continue;
  277|       |
  278|       |            // it's similar enough -> add it to the smoothing group
  279|  2.57k|            closeVertices.push_back(idx);
  280|  2.57k|            vertexDone[idx] = true;
  281|  2.57k|        }
  282|       |
  283|       |        // smooth the tangents and bitangents of all vertices that were found to be close enough
  284|  3.33k|        aiVector3D smoothTangent(0, 0, 0), smoothBitangent(0, 0, 0);
  285|  9.24k|        for (unsigned int b = 0; b < closeVertices.size(); ++b) {
  ------------------
  |  Branch (285:34): [True: 5.91k, False: 3.33k]
  ------------------
  286|  5.91k|            smoothTangent += meshTang[closeVertices[b]];
  287|  5.91k|            smoothBitangent += meshBitang[closeVertices[b]];
  288|  5.91k|        }
  289|  3.33k|        smoothTangent.Normalize();
  290|  3.33k|        smoothBitangent.Normalize();
  291|       |
  292|       |        // and write it back into all affected tangents
  293|  9.24k|        for (unsigned int b = 0; b < closeVertices.size(); ++b) {
  ------------------
  |  Branch (293:34): [True: 5.91k, False: 3.33k]
  ------------------
  294|  5.91k|            meshTang[closeVertices[b]] = smoothTangent;
  295|  5.91k|            meshBitang[closeVertices[b]] = smoothBitangent;
  296|  5.91k|        }
  297|  3.33k|    }
  298|    231|    return true;
  299|    793|}

_ZNK6Assimp23ComputeUVMappingProcess8IsActiveEj:
   61|  1.48k|bool ComputeUVMappingProcess::IsActive(unsigned int pFlags) const {
   62|  1.48k|    return (pFlags & aiProcess_GenUVCoords) != 0;
   63|  1.48k|}
_ZN6Assimp23ComputeUVMappingProcess7ExecuteEP7aiScene:
  345|  1.48k|void ComputeUVMappingProcess::Execute(aiScene *pScene) {
  346|  1.48k|    ASSIMP_LOG_DEBUG("GenUVCoordsProcess begin");
  347|  1.48k|    char buffer[1024];
  348|       |
  349|  1.48k|    if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
  ------------------
  |  Branch (349:9): [True: 0, False: 1.48k]
  ------------------
  350|      0|        throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
  351|      0|    }
  352|       |
  353|  1.48k|    std::list<MappingInfo> mappingStack;
  354|       |
  355|       |    // Iterate through all materials and search for non-UV mapped textures
  356|  2.81k|    for (unsigned int i = 0; i < pScene->mNumMaterials; ++i) {
  ------------------
  |  Branch (356:30): [True: 1.32k, False: 1.48k]
  ------------------
  357|  1.32k|        mappingStack.clear();
  358|  1.32k|        aiMaterial *mat = pScene->mMaterials[i];
  359|  1.32k|        if (mat == nullptr) {
  ------------------
  |  Branch (359:13): [True: 0, False: 1.32k]
  ------------------
  360|      0|            ASSIMP_LOG_INFO("Material pointer in nullptr, skipping.");
  361|      0|            continue;
  362|      0|        }
  363|  17.3k|        for (unsigned int a = 0; a < mat->mNumProperties; ++a) {
  ------------------
  |  Branch (363:34): [True: 16.0k, False: 1.32k]
  ------------------
  364|  16.0k|            aiMaterialProperty *prop = mat->mProperties[a];
  365|  16.0k|            if (!::strcmp(prop->mKey.data, "$tex.mapping")) {
  ------------------
  |  Branch (365:17): [True: 0, False: 16.0k]
  ------------------
  366|      0|                aiTextureMapping &mapping = *((aiTextureMapping *)prop->mData);
  367|      0|                if (aiTextureMapping_UV != mapping) {
  ------------------
  |  Branch (367:21): [True: 0, False: 0]
  ------------------
  368|      0|                    if (!DefaultLogger::isNullLogger()) {
  ------------------
  |  Branch (368:25): [True: 0, False: 0]
  ------------------
  369|      0|                        ai_snprintf(buffer, 1024, "Found non-UV mapped texture (%s,%u). Mapping type: %s",
  370|      0|                                aiTextureTypeToString((aiTextureType)prop->mSemantic), prop->mIndex,
  371|      0|                                MappingTypeToString(mapping));
  372|       |
  373|      0|                        ASSIMP_LOG_INFO(buffer);
  374|      0|                    }
  375|       |
  376|      0|                    if (aiTextureMapping_OTHER == mapping)
  ------------------
  |  Branch (376:25): [True: 0, False: 0]
  ------------------
  377|      0|                        continue;
  378|       |
  379|      0|                    MappingInfo info(mapping);
  380|       |
  381|       |                    // Get further properties - currently only the major axis
  382|      0|                    for (unsigned int a2 = 0; a2 < mat->mNumProperties; ++a2) {
  ------------------
  |  Branch (382:47): [True: 0, False: 0]
  ------------------
  383|      0|                        aiMaterialProperty *prop2 = mat->mProperties[a2];
  384|      0|                        if (prop2->mSemantic != prop->mSemantic || prop2->mIndex != prop->mIndex)
  ------------------
  |  Branch (384:29): [True: 0, False: 0]
  |  Branch (384:68): [True: 0, False: 0]
  ------------------
  385|      0|                            continue;
  386|       |
  387|      0|                        if (!::strcmp(prop2->mKey.data, "$tex.mapaxis")) {
  ------------------
  |  Branch (387:29): [True: 0, False: 0]
  ------------------
  388|      0|                            info.axis = *((aiVector3D *)prop2->mData);
  389|      0|                            break;
  390|      0|                        }
  391|      0|                    }
  392|       |
  393|      0|                    unsigned int idx(99999999);
  394|       |
  395|       |                    // Check whether we have this mapping mode already
  396|      0|                    std::list<MappingInfo>::iterator it = std::find(mappingStack.begin(), mappingStack.end(), info);
  397|      0|                    if (mappingStack.end() != it) {
  ------------------
  |  Branch (397:25): [True: 0, False: 0]
  ------------------
  398|      0|                        idx = (*it).uv;
  399|      0|                    } else {
  400|       |                        /*  We have found a non-UV mapped texture. Now
  401|       |                         *   we need to find all meshes using this material
  402|       |                         *   that we can compute UV channels for them.
  403|       |                         */
  404|      0|                        for (unsigned int m = 0; m < pScene->mNumMeshes; ++m) {
  ------------------
  |  Branch (404:50): [True: 0, False: 0]
  ------------------
  405|      0|                            aiMesh *mesh = pScene->mMeshes[m];
  406|      0|                            unsigned int outIdx = 0;
  407|      0|                            if (mesh->mMaterialIndex != i || (outIdx = FindEmptyUVChannel(mesh)) == UINT_MAX ||
  ------------------
  |  Branch (407:33): [True: 0, False: 0]
  |  Branch (407:62): [True: 0, False: 0]
  ------------------
  408|      0|                                    !mesh->mNumVertices) {
  ------------------
  |  Branch (408:37): [True: 0, False: 0]
  ------------------
  409|      0|                                continue;
  410|      0|                            }
  411|       |
  412|       |                            // Allocate output storage
  413|      0|                            aiVector3D *p = mesh->mTextureCoords[outIdx] = new aiVector3D[mesh->mNumVertices];
  414|       |
  415|      0|                            switch (mapping) {
  416|      0|                            case aiTextureMapping_SPHERE:
  ------------------
  |  Branch (416:29): [True: 0, False: 0]
  ------------------
  417|      0|                                ComputeSphereMapping(mesh, info.axis, p);
  418|      0|                                break;
  419|      0|                            case aiTextureMapping_CYLINDER:
  ------------------
  |  Branch (419:29): [True: 0, False: 0]
  ------------------
  420|      0|                                ComputeCylinderMapping(mesh, info.axis, p);
  421|      0|                                break;
  422|      0|                            case aiTextureMapping_PLANE:
  ------------------
  |  Branch (422:29): [True: 0, False: 0]
  ------------------
  423|      0|                                ComputePlaneMapping(mesh, info.axis, p);
  424|      0|                                break;
  425|      0|                            case aiTextureMapping_BOX:
  ------------------
  |  Branch (425:29): [True: 0, False: 0]
  ------------------
  426|      0|                                ComputeBoxMapping(mesh, p);
  427|      0|                                break;
  428|      0|                            default:
  ------------------
  |  Branch (428:29): [True: 0, False: 0]
  ------------------
  429|      0|                                ai_assert(false);
  430|      0|                            }
  431|      0|                            if (m && idx != outIdx) {
  ------------------
  |  Branch (431:33): [True: 0, False: 0]
  |  Branch (431:38): [True: 0, False: 0]
  ------------------
  432|      0|                                ASSIMP_LOG_WARN("UV index mismatch. Not all meshes assigned to "
  433|      0|                                                "this material have equal numbers of UV channels. The UV index stored in  "
  434|      0|                                                "the material structure does therefore not apply for all meshes. ");
  435|      0|                            }
  436|      0|                            idx = outIdx;
  437|      0|                        }
  438|      0|                        info.uv = idx;
  439|      0|                        mappingStack.push_back(info);
  440|      0|                    }
  441|       |
  442|       |                    // Update the material property list
  443|      0|                    mapping = aiTextureMapping_UV;
  444|      0|                    ((aiMaterial *)mat)->AddProperty(&idx, 1, AI_MATKEY_UVWSRC(prop->mSemantic, prop->mIndex));
  445|      0|                }
  446|      0|            }
  447|  16.0k|        }
  448|  1.32k|    }
  449|  1.48k|    ASSIMP_LOG_DEBUG("GenUVCoordsProcess finished");
  450|  1.48k|}

_ZN6Assimp23ComputeUVMappingProcessC2Ev:
   63|  3.48k|    ComputeUVMappingProcess() = default;

_ZNK6Assimp21MakeLeftHandedProcess8IsActiveEj:
   82|  1.48k|bool MakeLeftHandedProcess::IsActive(unsigned int pFlags) const {
   83|  1.48k|    return 0 != (pFlags & aiProcess_MakeLeftHanded);
   84|  1.48k|}
_ZN6Assimp14FlipUVsProcessC2Ev:
  244|  3.48k|FlipUVsProcess::FlipUVsProcess() = default;
_ZN6Assimp14FlipUVsProcessD2Ev:
  248|  3.48k|FlipUVsProcess::~FlipUVsProcess() = default;
_ZNK6Assimp14FlipUVsProcess8IsActiveEj:
  252|  1.48k|bool FlipUVsProcess::IsActive(unsigned int pFlags) const {
  253|  1.48k|    return 0 != (pFlags & aiProcess_FlipUVs);
  254|  1.48k|}
_ZNK6Assimp23FlipWindingOrderProcess8IsActiveEj:
  306|  1.48k|bool FlipWindingOrderProcess::IsActive(unsigned int pFlags) const {
  307|  1.48k|    return 0 != (pFlags & aiProcess_FlipWindingOrder);
  308|  1.48k|}

_ZN6Assimp21MakeLeftHandedProcessC2Ev:
   77|  3.48k|    MakeLeftHandedProcess() = default;
_ZN6Assimp23FlipWindingOrderProcessC2Ev:
  132|  3.48k|    FlipWindingOrderProcess() = default;

_ZN6Assimp13DeboneProcessC2Ev:
   54|  3.48k|DeboneProcess::DeboneProcess() : mNumBones(0), mNumBonesCanDoWithout(0), mThreshold(AI_DEBONE_THRESHOLD), mAllOrNone(false) {}
_ZNK6Assimp13DeboneProcess8IsActiveEj:
   58|  1.43k|bool DeboneProcess::IsActive( unsigned int pFlags) const {
   59|  1.43k|    return (pFlags & aiProcess_Debone) != 0;
   60|  1.43k|}

_ZN6Assimp13DeboneProcessD2Ev:
   72|  3.48k|    ~DeboneProcess() override = default;

_ZNK6Assimp22DropFaceNormalsProcess8IsActiveEj:
   58|  1.43k|bool DropFaceNormalsProcess::IsActive(unsigned int pFlags) const {
   59|  1.43k|    return (pFlags & aiProcess_DropNormals) != 0;
   60|  1.43k|}

_ZN6Assimp22DropFaceNormalsProcessC2Ev:
   57|  3.48k|    DropFaceNormalsProcess() = default;

_ZNK6Assimp20EmbedTexturesProcess8IsActiveEj:
   53|  1.48k|bool EmbedTexturesProcess::IsActive(unsigned int pFlags) const {
   54|  1.48k|    return (pFlags & aiProcess_EmbedTextures) != 0;
   55|  1.48k|}

_ZN6Assimp20EmbedTexturesProcessC2Ev:
   64|  3.48k|    EmbedTexturesProcess() = default;
_ZN6Assimp20EmbedTexturesProcessD2Ev:
   67|  3.48k|    ~EmbedTexturesProcess() override = default;

_ZN6Assimp22FindDegeneratesProcessC2Ev:
   62|  3.48k|        mConfigRemoveDegenerates(false),
   63|  3.48k|        mConfigCheckAreaOfTriangle(false) {
   64|       |    // empty
   65|  3.48k|}
_ZNK6Assimp22FindDegeneratesProcess8IsActiveEj:
   69|  1.48k|bool FindDegeneratesProcess::IsActive(unsigned int pFlags) const {
   70|  1.48k|    return 0 != (pFlags & aiProcess_FindDegenerates);
   71|  1.48k|}
_ZN6Assimp22FindDegeneratesProcess15SetupPropertiesEPKNS_8ImporterE:
   75|  1.48k|void FindDegeneratesProcess::SetupProperties(const Importer *pImp) {
   76|       |    // Get the current value of AI_CONFIG_PP_FD_REMOVE
   77|  1.48k|    mConfigRemoveDegenerates = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_REMOVE, 0));
   78|       |    mConfigCheckAreaOfTriangle = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_CHECKAREA));
   79|  1.48k|}
_ZN6Assimp22FindDegeneratesProcess7ExecuteEP7aiScene:
   83|  1.48k|void FindDegeneratesProcess::Execute(aiScene *pScene) {
   84|  1.48k|    ASSIMP_LOG_DEBUG("FindDegeneratesProcess begin");
   85|  1.48k|    if (nullptr == pScene) {
  ------------------
  |  Branch (85:9): [True: 0, False: 1.48k]
  ------------------
   86|      0|        return;
   87|      0|    }
   88|       |
   89|  1.48k|    std::unordered_map<unsigned int, unsigned int> meshMap;
   90|  1.48k|    meshMap.reserve(pScene->mNumMeshes);
   91|       |
   92|  1.48k|    const unsigned int originalNumMeshes = pScene->mNumMeshes;
   93|  1.48k|    unsigned int targetIndex = 0;
   94|  2.81k|    for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
  ------------------
  |  Branch (94:30): [True: 1.32k, False: 1.48k]
  ------------------
   95|       |        // Do not process point cloud, ExecuteOnMesh works only with faces data
   96|  1.32k|        if ((pScene->mMeshes[i]->mPrimitiveTypes != aiPrimitiveType::aiPrimitiveType_POINT) && ExecuteOnMesh(pScene->mMeshes[i])) {
  ------------------
  |  Branch (96:13): [True: 1.28k, False: 46]
  |  Branch (96:96): [True: 0, False: 1.28k]
  ------------------
   97|      0|            delete pScene->mMeshes[i];
   98|       |            // Not strictly required, but clean:
   99|      0|            pScene->mMeshes[i] = nullptr;
  100|  1.32k|        } else {
  101|  1.32k|            meshMap[i] = targetIndex;
  102|  1.32k|            pScene->mMeshes[targetIndex] = pScene->mMeshes[i];
  103|  1.32k|            ++targetIndex;
  104|  1.32k|        }
  105|  1.32k|    }
  106|  1.48k|    pScene->mNumMeshes = targetIndex;
  107|       |
  108|  1.48k|    if (meshMap.size() < originalNumMeshes) {
  ------------------
  |  Branch (108:9): [True: 0, False: 1.48k]
  ------------------
  109|      0|        updateSceneGraph(pScene->mRootNode, meshMap);
  110|      0|    }
  111|       |
  112|       |    ASSIMP_LOG_DEBUG("FindDegeneratesProcess finished");
  113|  1.48k|}
_ZN6Assimp22FindDegeneratesProcess13ExecuteOnMeshEP6aiMesh:
  134|  1.28k|bool FindDegeneratesProcess::ExecuteOnMesh(aiMesh *mesh) {
  135|  1.28k|    mesh->mPrimitiveTypes = 0;
  136|       |
  137|  1.28k|    std::vector<bool> remove_me;
  138|  1.28k|    if (mConfigRemoveDegenerates) {
  ------------------
  |  Branch (138:9): [True: 0, False: 1.28k]
  ------------------
  139|      0|        remove_me.resize(mesh->mNumFaces, false);
  140|      0|    }
  141|       |
  142|  1.28k|    unsigned int deg = 0, limit;
  143|  34.4k|    for (unsigned int a = 0; a < mesh->mNumFaces; ++a) {
  ------------------
  |  Branch (143:30): [True: 33.1k, False: 1.28k]
  ------------------
  144|  33.1k|        aiFace &face = mesh->mFaces[a];
  145|  33.1k|        bool first = true;
  146|  33.1k|        auto vertex_in_range = [numVertices = mesh->mNumVertices](unsigned int vertex_idx) { return vertex_idx < numVertices; };
  147|       |
  148|       |        // check whether the face contains degenerated entries
  149|   112k|        for (unsigned int i = 0; i < face.mNumIndices; ++i) {
  ------------------
  |  Branch (149:34): [True: 79.2k, False: 33.1k]
  ------------------
  150|  79.2k|            if (!std::all_of(face.mIndices, face.mIndices + face.mNumIndices, vertex_in_range))
  ------------------
  |  Branch (150:17): [True: 0, False: 79.2k]
  ------------------
  151|      0|                continue;
  152|       |
  153|       |            // Polygons with more than 4 points are allowed to have double points, that is
  154|       |            // simulating polygons with holes just with concave polygons. However,
  155|       |            // double points may not come directly after another.
  156|  79.2k|            limit = face.mNumIndices;
  157|  79.2k|            if (face.mNumIndices > 4) {
  ------------------
  |  Branch (157:17): [True: 0, False: 79.2k]
  ------------------
  158|      0|                limit = std::min(limit, i + 2);
  159|      0|            }
  160|       |
  161|   160k|            for (unsigned int t = i + 1; t < limit; ++t) {
  ------------------
  |  Branch (161:42): [True: 81.7k, False: 79.2k]
  ------------------
  162|  81.7k|                if (mesh->mVertices[face.mIndices[i]] == mesh->mVertices[face.mIndices[t]]) {
  ------------------
  |  Branch (162:21): [True: 14.9k, False: 66.8k]
  ------------------
  163|       |                    // we have found a matching vertex position
  164|       |                    // remove the corresponding index from the array
  165|  14.9k|                    --face.mNumIndices;
  166|  14.9k|                    --limit;
  167|  19.9k|                    for (unsigned int m = t; m < face.mNumIndices; ++m) {
  ------------------
  |  Branch (167:46): [True: 5.02k, False: 14.9k]
  ------------------
  168|  5.02k|                        face.mIndices[m] = face.mIndices[m + 1];
  169|  5.02k|                    }
  170|  14.9k|                    --t;
  171|       |
  172|       |                    // NOTE: we set the removed vertex index to an unique value
  173|       |                    // to make sure the developer gets notified when his
  174|       |                    // application attempts to access this data.
  175|  14.9k|                    face.mIndices[face.mNumIndices] = 0xdeadbeef;
  176|       |
  177|  14.9k|                    if (first) {
  ------------------
  |  Branch (177:25): [True: 11.6k, False: 3.35k]
  ------------------
  178|  11.6k|                        ++deg;
  179|  11.6k|                        first = false;
  180|  11.6k|                    }
  181|       |
  182|  14.9k|                    if (mConfigRemoveDegenerates) {
  ------------------
  |  Branch (182:25): [True: 0, False: 14.9k]
  ------------------
  183|      0|                        remove_me[a] = true;
  184|      0|                        goto evil_jump_outside; // hrhrhrh ... yeah, this rocks baby!
  185|      0|                    }
  186|  14.9k|                }
  187|  81.7k|            }
  188|       |
  189|  79.2k|            if (mConfigCheckAreaOfTriangle) {
  ------------------
  |  Branch (189:17): [True: 79.2k, False: 0]
  ------------------
  190|  79.2k|                if (face.mNumIndices == 3) {
  ------------------
  |  Branch (190:21): [True: 57.2k, False: 21.9k]
  ------------------
  191|  57.2k|                    ai_real area = GeometryUtils::calculateAreaOfTriangle(face, mesh);
  192|  57.2k|                    if (area < ai_epsilon) {
  ------------------
  |  Branch (192:25): [True: 48.3k, False: 8.89k]
  ------------------
  193|  48.3k|                        if (mConfigRemoveDegenerates) {
  ------------------
  |  Branch (193:29): [True: 0, False: 48.3k]
  ------------------
  194|      0|                            remove_me[a] = true;
  195|      0|                            ++deg;
  196|      0|                            goto evil_jump_outside;
  197|      0|                        }
  198|       |
  199|       |                        // todo: check for index which is corrupt.
  200|  48.3k|                    }
  201|  57.2k|                }
  202|  79.2k|            }
  203|  79.2k|        }
  204|       |
  205|       |        // We need to update the primitive flags array of the mesh.
  206|  33.1k|        switch (face.mNumIndices) {
  207|  5.36k|        case 1u:
  ------------------
  |  Branch (207:9): [True: 5.36k, False: 27.7k]
  ------------------
  208|  5.36k|            mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
  209|  5.36k|            break;
  210|  9.52k|        case 2u:
  ------------------
  |  Branch (210:9): [True: 9.52k, False: 23.6k]
  ------------------
  211|  9.52k|            mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
  212|  9.52k|            break;
  213|  18.2k|        case 3u:
  ------------------
  |  Branch (213:9): [True: 18.2k, False: 14.8k]
  ------------------
  214|  18.2k|            mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
  215|  18.2k|            break;
  216|      0|        default:
  ------------------
  |  Branch (216:9): [True: 0, False: 33.1k]
  ------------------
  217|      0|            mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
  218|      0|            break;
  219|  33.1k|        };
  220|  33.1k|    evil_jump_outside:
  221|  33.1k|        continue;
  222|  33.1k|    }
  223|       |
  224|       |    // If AI_CONFIG_PP_FD_REMOVE is true, remove degenerated faces from the import
  225|  1.28k|    if (mConfigRemoveDegenerates && deg) {
  ------------------
  |  Branch (225:9): [True: 0, False: 1.28k]
  |  Branch (225:37): [True: 0, False: 0]
  ------------------
  226|      0|        unsigned int n = 0;
  227|      0|        for (unsigned int a = 0; a < mesh->mNumFaces; ++a) {
  ------------------
  |  Branch (227:34): [True: 0, False: 0]
  ------------------
  228|      0|            aiFace &face_src = mesh->mFaces[a];
  229|      0|            if (!remove_me[a]) {
  ------------------
  |  Branch (229:17): [True: 0, False: 0]
  ------------------
  230|      0|                aiFace &face_dest = mesh->mFaces[n++];
  231|       |
  232|       |                // Do a manual copy, keep the index array
  233|      0|                face_dest.mNumIndices = face_src.mNumIndices;
  234|      0|                face_dest.mIndices = face_src.mIndices;
  235|       |
  236|      0|                if (&face_src != &face_dest) {
  ------------------
  |  Branch (236:21): [True: 0, False: 0]
  ------------------
  237|       |                    // clear source
  238|      0|                    face_src.mNumIndices = 0;
  239|      0|                    face_src.mIndices = nullptr;
  240|      0|                }
  241|      0|            } else {
  242|       |                // Otherwise delete it if we don't need this face
  243|      0|                delete[] face_src.mIndices;
  244|      0|                face_src.mIndices = nullptr;
  245|      0|                face_src.mNumIndices = 0;
  246|      0|            }
  247|      0|        }
  248|       |        // Just leave the rest of the array unreferenced, we don't care for now
  249|      0|        mesh->mNumFaces = n;
  250|      0|        if (!mesh->mNumFaces) {
  ------------------
  |  Branch (250:13): [True: 0, False: 0]
  ------------------
  251|       |            // The whole mesh consists of degenerated faces
  252|       |            // signal upward, that this mesh should be deleted.
  253|      0|            ASSIMP_LOG_VERBOSE_DEBUG("FindDegeneratesProcess removed a mesh full of degenerated primitives");
  254|      0|            return true;
  255|      0|        }
  256|      0|    }
  257|       |
  258|  1.28k|    if (deg && !DefaultLogger::isNullLogger()) {
  ------------------
  |  Branch (258:9): [True: 1.06k, False: 212]
  |  Branch (258:16): [True: 0, False: 1.06k]
  ------------------
  259|       |        ASSIMP_LOG_WARN("Found ", deg, " degenerated primitives");
  260|      0|    }
  261|  1.28k|    return false;
  262|  1.28k|}
FindDegenerates.cpp:_ZZN6Assimp22FindDegeneratesProcess13ExecuteOnMeshEP6aiMeshENK3$_0clEj:
  146|   225k|        auto vertex_in_range = [numVertices = mesh->mNumVertices](unsigned int vertex_idx) { return vertex_idx < numVertices; };

_ZN6Assimp20FindInstancesProcessC2Ev:
   58|  3.48k|:   configSpeedFlag (false)
   59|  3.48k|{}
_ZNK6Assimp20FindInstancesProcess8IsActiveEj:
   64|  1.48k|{
   65|       |    // FindInstances makes absolutely no sense together with PreTransformVertices
   66|       |    // fixme: spawn error message somewhere else?
   67|  1.48k|    return 0 != (pFlags & aiProcess_FindInstances) && 0 == (pFlags & aiProcess_PreTransformVertices);
  ------------------
  |  Branch (67:12): [True: 0, False: 1.48k]
  |  Branch (67:55): [True: 0, False: 0]
  ------------------
   68|  1.48k|}

_ZN6Assimp22FindInvalidDataProcessC2Ev:
   59|  3.48k|        configEpsilon(0.0), mIgnoreTexCoods(false) {
   60|       |    // nothing to do here
   61|  3.48k|}
_ZNK6Assimp22FindInvalidDataProcess8IsActiveEj:
   65|  1.48k|bool FindInvalidDataProcess::IsActive(unsigned int pFlags) const {
   66|  1.48k|    return 0 != (pFlags & aiProcess_FindInvalidData);
   67|  1.48k|}
_ZN6Assimp22FindInvalidDataProcess15SetupPropertiesEPKNS_8ImporterE:
   71|  1.48k|void FindInvalidDataProcess::SetupProperties(const Importer *pImp) {
   72|       |    // Get the current value of AI_CONFIG_PP_FID_ANIM_ACCURACY
   73|  1.48k|    configEpsilon = (0 != pImp->GetPropertyFloat(AI_CONFIG_PP_FID_ANIM_ACCURACY, 0.f));
   74|       |    mIgnoreTexCoods = pImp->GetPropertyBool(AI_CONFIG_PP_FID_IGNORE_TEXTURECOORDS, false);
   75|  1.48k|}
_Z20UpdateMeshReferencesP6aiNodeRKNSt3__16vectorIjNS1_9allocatorIjEEEE:
   79|  1.54k|void UpdateMeshReferences(aiNode *node, const std::vector<unsigned int> &meshMapping) {
   80|  1.54k|    if (node->mNumMeshes) {
  ------------------
  |  Branch (80:9): [True: 305, False: 1.23k]
  ------------------
   81|    305|        unsigned int out = 0;
   82|  1.07k|        for (unsigned int a = 0; a < node->mNumMeshes; ++a) {
  ------------------
  |  Branch (82:34): [True: 769, False: 305]
  ------------------
   83|       |
   84|    769|            unsigned int ref = node->mMeshes[a];
   85|    769|            if (ref >= meshMapping.size())
  ------------------
  |  Branch (85:17): [True: 0, False: 769]
  ------------------
   86|      0|                throw DeadlyImportError("Invalid mesh ref");
   87|       |
   88|    769|            if (UINT_MAX != (ref = meshMapping[ref])) {
  ------------------
  |  Branch (88:17): [True: 455, False: 314]
  ------------------
   89|    455|                node->mMeshes[out++] = ref;
   90|    455|            }
   91|    769|        }
   92|       |        // just let the members that are unused, that's much cheaper
   93|       |        // than a full array realloc'n'copy party ...
   94|    305|        node->mNumMeshes = out;
   95|    305|        if (0 == out) {
  ------------------
  |  Branch (95:13): [True: 0, False: 305]
  ------------------
   96|      0|            delete[] node->mMeshes;
   97|      0|            node->mMeshes = nullptr;
   98|      0|        }
   99|    305|    }
  100|       |    // recursively update all children
  101|  2.80k|    for (unsigned int i = 0; i < node->mNumChildren; ++i) {
  ------------------
  |  Branch (101:30): [True: 1.26k, False: 1.54k]
  ------------------
  102|  1.26k|        UpdateMeshReferences(node->mChildren[i], meshMapping);
  103|  1.26k|    }
  104|  1.54k|}
_ZN6Assimp22FindInvalidDataProcess7ExecuteEP7aiScene:
  108|  1.48k|void FindInvalidDataProcess::Execute(aiScene *pScene) {
  109|  1.48k|    ASSIMP_LOG_DEBUG("FindInvalidDataProcess begin");
  110|       |
  111|  1.48k|    bool out = false;
  112|  1.48k|    std::vector<unsigned int> meshMapping(pScene->mNumMeshes);
  113|  1.48k|    unsigned int real = 0;
  114|       |
  115|       |    // Process meshes
  116|  3.97k|    for (unsigned int a = 0; a < pScene->mNumMeshes; a++) {
  ------------------
  |  Branch (116:30): [True: 2.48k, False: 1.48k]
  ------------------
  117|  2.48k|        int result = ProcessMesh(pScene->mMeshes[a]);
  118|  2.48k|        if (0 == result) {
  ------------------
  |  Branch (118:13): [True: 1.83k, False: 657]
  ------------------
  119|  1.83k|            out = true;
  120|  1.83k|        }
  121|  2.48k|        if (2 == result) {
  ------------------
  |  Branch (121:13): [True: 372, False: 2.11k]
  ------------------
  122|       |            // remove this mesh
  123|    372|            delete pScene->mMeshes[a];
  124|    372|            pScene->mMeshes[a] = nullptr;
  125|       |
  126|    372|            meshMapping[a] = UINT_MAX;
  127|    372|            out = true;
  128|    372|            continue;
  129|    372|        }
  130|       |
  131|  2.11k|        pScene->mMeshes[real] = pScene->mMeshes[a];
  132|  2.11k|        meshMapping[a] = real++;
  133|  2.11k|    }
  134|       |
  135|       |    // Process animations
  136|  1.48k|    for (unsigned int animIdx = 0; animIdx < pScene->mNumAnimations; ++animIdx) {
  ------------------
  |  Branch (136:36): [True: 0, False: 1.48k]
  ------------------
  137|      0|        ProcessAnimation(pScene->mAnimations[animIdx]);
  138|      0|    }
  139|       |
  140|  1.48k|    if (out) {
  ------------------
  |  Branch (140:9): [True: 1.27k, False: 210]
  ------------------
  141|  1.27k|        if (real != pScene->mNumMeshes) {
  ------------------
  |  Branch (141:13): [True: 332, False: 943]
  ------------------
  142|    332|            if (!real) {
  ------------------
  |  Branch (142:17): [True: 53, False: 279]
  ------------------
  143|     53|                throw DeadlyImportError("No meshes remaining");
  144|     53|            }
  145|       |
  146|       |            // we need to remove some meshes.
  147|       |            // therefore we'll also need to remove all references
  148|       |            // to them from the scenegraph
  149|    279|            try {
  150|    279|                UpdateMeshReferences(pScene->mRootNode, meshMapping);
  151|    279|            } catch (const std::exception&) {
  152|       |                // fix the real number of meshes otherwise we'll get double free in the scene destructor
  153|      0|                pScene->mNumMeshes = real;
  154|      0|                throw;
  155|      0|            }
  156|    279|            pScene->mNumMeshes = real;
  157|    279|        }
  158|       |
  159|  1.27k|        ASSIMP_LOG_INFO("FindInvalidDataProcess finished. Found issues ...");
  160|  1.22k|    } else {
  161|       |        ASSIMP_LOG_DEBUG("FindInvalidDataProcess finished. Everything seems to be OK.");
  162|    210|    }
  163|  1.48k|}
_ZN6Assimp22FindInvalidDataProcess11ProcessMeshEP6aiMesh:
  323|  2.48k|int FindInvalidDataProcess::ProcessMesh(aiMesh *pMesh) {
  324|  2.48k|    bool ret = false;
  325|  2.48k|    std::vector<bool> dirtyMask(pMesh->mNumVertices, pMesh->mNumFaces != 0);
  326|       |
  327|       |    // Ignore elements that are not referenced by vertices.
  328|       |    // (they are, for example, caused by the FindDegenerates step)
  329|  36.6k|    for (unsigned int m = 0; m < pMesh->mNumFaces; ++m) {
  ------------------
  |  Branch (329:30): [True: 34.1k, False: 2.48k]
  ------------------
  330|  34.1k|        const aiFace &f = pMesh->mFaces[m];
  331|       |
  332|   114k|        for (unsigned int i = 0; i < f.mNumIndices; ++i) {
  ------------------
  |  Branch (332:34): [True: 80.2k, False: 34.1k]
  ------------------
  333|  80.2k|            dirtyMask[f.mIndices[i]] = false;
  334|  80.2k|        }
  335|  34.1k|    }
  336|       |
  337|       |    // Process vertex positions
  338|  2.48k|    if (pMesh->mVertices && ProcessArray(pMesh->mVertices, pMesh->mNumVertices, "positions", dirtyMask)) {
  ------------------
  |  Branch (338:9): [True: 2.48k, False: 0]
  |  Branch (338:29): [True: 372, False: 2.11k]
  ------------------
  339|    372|        ASSIMP_LOG_ERROR("Deleting mesh: Unable to continue without vertex positions");
  340|       |
  341|    372|        return 2;
  342|    372|    }
  343|       |
  344|       |    // process texture coordinates
  345|  2.11k|    if (!mIgnoreTexCoods) {
  ------------------
  |  Branch (345:9): [True: 2.11k, False: 0]
  ------------------
  346|  2.68k|        for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS && pMesh->mTextureCoords[i]; ++i) {
  ------------------
  |  Branch (346:34): [True: 2.68k, False: 0]
  |  Branch (346:72): [True: 565, False: 2.11k]
  ------------------
  347|    565|            if (ProcessArray(pMesh->mTextureCoords[i], pMesh->mNumVertices, "uvcoords", dirtyMask)) {
  ------------------
  |  Branch (347:17): [True: 94, False: 471]
  ------------------
  348|     94|                pMesh->mNumUVComponents[i] = 0;
  349|       |
  350|       |                // delete all subsequent texture coordinate sets.
  351|    752|                for (unsigned int a = i + 1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
  ------------------
  |  Branch (351:46): [True: 658, False: 94]
  ------------------
  352|    658|                    delete[] pMesh->mTextureCoords[a];
  353|    658|                    pMesh->mTextureCoords[a] = nullptr;
  354|    658|                    pMesh->mNumUVComponents[a] = 0;
  355|    658|                }
  356|       |
  357|     94|                ret = true;
  358|     94|            }
  359|    565|        }
  360|  2.11k|    }
  361|       |
  362|       |    // -- we don't validate vertex colors, it's difficult to say whether
  363|       |    // they are invalid or not.
  364|       |
  365|       |    // Normals and tangents are undefined for point and line faces.
  366|  2.11k|    if (pMesh->mNormals || pMesh->mTangents) {
  ------------------
  |  Branch (366:9): [True: 1.16k, False: 947]
  |  Branch (366:28): [True: 0, False: 947]
  ------------------
  367|       |
  368|  1.16k|        if (aiPrimitiveType_POINT & pMesh->mPrimitiveTypes ||
  ------------------
  |  Branch (368:13): [True: 242, False: 927]
  ------------------
  369|    927|                aiPrimitiveType_LINE & pMesh->mPrimitiveTypes) {
  ------------------
  |  Branch (369:17): [True: 500, False: 427]
  ------------------
  370|    742|            if (aiPrimitiveType_TRIANGLE & pMesh->mPrimitiveTypes ||
  ------------------
  |  Branch (370:17): [True: 0, False: 742]
  ------------------
  371|    742|                    aiPrimitiveType_POLYGON & pMesh->mPrimitiveTypes) {
  ------------------
  |  Branch (371:21): [True: 0, False: 742]
  ------------------
  372|       |                // We need to update the lookup-table
  373|      0|                for (unsigned int m = 0; m < pMesh->mNumFaces; ++m) {
  ------------------
  |  Branch (373:42): [True: 0, False: 0]
  ------------------
  374|      0|                    const aiFace &f = pMesh->mFaces[m];
  375|       |
  376|      0|                    if (f.mNumIndices < 3) {
  ------------------
  |  Branch (376:25): [True: 0, False: 0]
  ------------------
  377|      0|                        dirtyMask[f.mIndices[0]] = true;
  378|      0|                        if (f.mNumIndices == 2) {
  ------------------
  |  Branch (378:29): [True: 0, False: 0]
  ------------------
  379|      0|                            dirtyMask[f.mIndices[1]] = true;
  380|      0|                        }
  381|      0|                    }
  382|      0|                }
  383|      0|            }
  384|       |            // Normals, tangents and bitangents are undefined for
  385|       |            // the whole mesh (and should not even be there)
  386|    742|            else {
  387|    742|                return ret;
  388|    742|            }
  389|    742|        }
  390|       |
  391|       |        // Process mesh normals
  392|    427|        if (pMesh->mNormals && ProcessArray(pMesh->mNormals, pMesh->mNumVertices,
  ------------------
  |  Branch (392:13): [True: 427, False: 0]
  |  Branch (392:32): [True: 193, False: 234]
  ------------------
  393|    427|                                       "normals", dirtyMask, true, false))
  394|    193|            ret = true;
  395|       |
  396|       |        // Process mesh tangents
  397|    427|        if (pMesh->mTangents && ProcessArray(pMesh->mTangents, pMesh->mNumVertices, "tangents", dirtyMask)) {
  ------------------
  |  Branch (397:13): [True: 21, False: 406]
  |  Branch (397:33): [True: 6, False: 15]
  ------------------
  398|      6|            delete[] pMesh->mBitangents;
  399|      6|            pMesh->mBitangents = nullptr;
  400|      6|            ret = true;
  401|      6|        }
  402|       |
  403|       |        // Process mesh bitangents
  404|    427|        if (pMesh->mBitangents && ProcessArray(pMesh->mBitangents, pMesh->mNumVertices, "bitangents", dirtyMask)) {
  ------------------
  |  Branch (404:13): [True: 15, False: 412]
  |  Branch (404:35): [True: 12, False: 3]
  ------------------
  405|     12|            delete[] pMesh->mTangents;
  406|     12|            pMesh->mTangents = nullptr;
  407|     12|            ret = true;
  408|     12|        }
  409|    427|    }
  410|  1.37k|    return ret ? 1 : 0;
  ------------------
  |  Branch (410:12): [True: 210, False: 1.16k]
  ------------------
  411|  2.11k|}
_Z12ProcessArrayI10aiVector3tIfEEbRPT_jPKcRKNSt3__16vectorIbNS7_9allocatorIbEEEEbb:
  203|  3.51k|        const std::vector<bool> &dirtyMask, bool mayBeIdentical = false, bool mayBeZero = true) {
  204|  3.51k|    const char *err = ValidateArrayContents(in, num, dirtyMask, mayBeIdentical, mayBeZero);
  205|  3.51k|    if (err) {
  ------------------
  |  Branch (205:9): [True: 677, False: 2.83k]
  ------------------
  206|    677|        ASSIMP_LOG_ERROR("FindInvalidDataProcess fails on mesh ", name, ": ", err);
  207|    677|        delete[] in;
  208|    677|        in = nullptr;
  209|    677|        return true;
  210|    677|    }
  211|  2.83k|    return false;
  212|  3.51k|}
_Z21ValidateArrayContentsI10aiVector3tIfEEPKcPKT_jRKNSt3__16vectorIbNS7_9allocatorIbEEEEbb:
  175|  3.51k|        const std::vector<bool> &dirtyMask, bool mayBeIdentical, bool mayBeZero) {
  176|  3.51k|    bool b = false;
  177|  3.51k|    unsigned int cnt = 0;
  178|  93.0k|    for (unsigned int i = 0; i < size; ++i) {
  ------------------
  |  Branch (178:30): [True: 89.8k, False: 3.18k]
  ------------------
  179|       |
  180|  89.8k|        if (dirtyMask.size() && dirtyMask[i]) {
  ------------------
  |  Branch (180:13): [True: 89.8k, False: 0]
  |  Branch (180:13): [True: 724, False: 89.0k]
  |  Branch (180:33): [True: 724, False: 89.0k]
  ------------------
  181|    724|            continue;
  182|    724|        }
  183|  89.0k|        ++cnt;
  184|       |
  185|  89.0k|        const aiVector3D &v = arr[i];
  186|  89.0k|        if (is_special_float(v.x) || is_special_float(v.y) || is_special_float(v.z)) {
  ------------------
  |  Branch (186:13): [True: 84, False: 89.0k]
  |  Branch (186:38): [True: 37, False: 88.9k]
  |  Branch (186:63): [True: 36, False: 88.9k]
  ------------------
  187|    157|            return "INF/NAN was found in a vector component";
  188|    157|        }
  189|  88.9k|        if (!mayBeZero && !v.x && !v.y && !v.z) {
  ------------------
  |  Branch (189:13): [True: 5.22k, False: 83.7k]
  |  Branch (189:27): [True: 2.04k, False: 3.17k]
  |  Branch (189:35): [True: 1.36k, False: 687]
  |  Branch (189:43): [True: 171, False: 1.19k]
  ------------------
  190|    171|            return "Found zero-length vector";
  191|    171|        }
  192|  88.7k|        if (i && v != arr[i - 1]) b = true;
  ------------------
  |  Branch (192:13): [True: 85.4k, False: 3.29k]
  |  Branch (192:18): [True: 69.4k, False: 16.0k]
  ------------------
  193|  88.7k|    }
  194|  3.18k|    if (cnt > 1 && !b && !mayBeIdentical) {
  ------------------
  |  Branch (194:9): [True: 2.90k, False: 280]
  |  Branch (194:20): [True: 370, False: 2.53k]
  |  Branch (194:26): [True: 349, False: 21]
  ------------------
  195|    349|        return "All vectors are identical";
  196|    349|    }
  197|  2.83k|    return nullptr;
  198|  3.18k|}

_ZNK6Assimp25FixInfacingNormalsProcess8IsActiveEj:
   61|  1.43k|bool FixInfacingNormalsProcess::IsActive( unsigned int pFlags) const {
   62|  1.43k|    return (pFlags & aiProcess_FixInfacingNormals) != 0;
   63|  1.43k|}

_ZN6Assimp25FixInfacingNormalsProcessC2Ev:
   62|  3.48k|    FixInfacingNormalsProcess() = default;

_ZNK6Assimp23GenBoundingBoxesProcess8IsActiveEj:
   51|  1.43k|bool GenBoundingBoxesProcess::IsActive(unsigned int pFlags) const {
   52|  1.43k|    return 0 != ( pFlags & aiProcess_GenBoundingBoxes );
   53|  1.43k|}

_ZN6Assimp23GenBoundingBoxesProcessC2Ev:
   65|  3.48k|    GenBoundingBoxesProcess() = default;

_ZNK6Assimp21GenFaceNormalsProcess8IsActiveEj:
   61|  1.43k|bool GenFaceNormalsProcess::IsActive(unsigned int pFlags) const {
   62|  1.43k|    force_ = (pFlags & aiProcess_ForceGenNormals) != 0;
   63|  1.43k|    flippedWindingOrder_ = (pFlags & aiProcess_FlipWindingOrder) != 0;
   64|  1.43k|    leftHanded_ = (pFlags & aiProcess_MakeLeftHanded) != 0;
   65|  1.43k|    return (pFlags & aiProcess_GenNormals) != 0;
   66|  1.43k|}

_ZN6Assimp21GenFaceNormalsProcessC2Ev:
   59|  3.48k|    GenFaceNormalsProcess() = default;

_ZN6Assimp23GenVertexNormalsProcessC2Ev:
   57|  3.48k|        configMaxAngle(AI_DEG_TO_RAD(175.f)) {
   58|       |    // empty
   59|  3.48k|}
_ZNK6Assimp23GenVertexNormalsProcess8IsActiveEj:
   63|  1.43k|bool GenVertexNormalsProcess::IsActive(unsigned int pFlags) const {
   64|  1.43k|    force_ = (pFlags & aiProcess_ForceGenNormals) != 0;
   65|  1.43k|    flippedWindingOrder_ = (pFlags & aiProcess_FlipWindingOrder) != 0;
   66|  1.43k|    leftHanded_ = (pFlags & aiProcess_MakeLeftHanded) != 0;
   67|  1.43k|    return (pFlags & aiProcess_GenSmoothNormals) != 0;
   68|  1.43k|}
_ZN6Assimp23GenVertexNormalsProcess15SetupPropertiesEPKNS_8ImporterE:
   72|  1.43k|void GenVertexNormalsProcess::SetupProperties(const Importer *pImp) {
   73|       |    // Get the current value of the AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE property
   74|  1.43k|    configMaxAngle = pImp->GetPropertyFloat(AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE, (ai_real)175.0);
   75|       |    configMaxAngle = AI_DEG_TO_RAD(std::max(std::min(configMaxAngle, (ai_real)175.0), (ai_real)0.0));
   76|  1.43k|}
_ZN6Assimp23GenVertexNormalsProcess7ExecuteEP7aiScene:
   80|  1.43k|void GenVertexNormalsProcess::Execute(aiScene *pScene) {
   81|  1.43k|    ASSIMP_LOG_DEBUG("GenVertexNormalsProcess begin");
   82|       |
   83|  1.43k|    if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
  ------------------
  |  Branch (83:9): [True: 0, False: 1.43k]
  ------------------
   84|      0|        throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
   85|      0|    }
   86|       |
   87|  1.43k|    bool bHas = false;
   88|  3.54k|    for (unsigned int a = 0; a < pScene->mNumMeshes; ++a) {
  ------------------
  |  Branch (88:30): [True: 2.11k, False: 1.43k]
  ------------------
   89|  2.11k|        if (GenMeshVertexNormals(pScene->mMeshes[a], a))
  ------------------
  |  Branch (89:13): [True: 562, False: 1.55k]
  ------------------
   90|    562|            bHas = true;
   91|  2.11k|    }
   92|       |
   93|  1.43k|    if (bHas) {
  ------------------
  |  Branch (93:9): [True: 562, False: 870]
  ------------------
   94|    562|        ASSIMP_LOG_INFO("GenVertexNormalsProcess finished. "
   95|    562|                        "Vertex normals have been calculated");
   96|    870|    } else {
   97|       |        ASSIMP_LOG_DEBUG("GenVertexNormalsProcess finished. "
   98|    870|                         "Normals are already there");
   99|    870|    }
  100|  1.43k|}
_ZN6Assimp23GenVertexNormalsProcess20GenMeshVertexNormalsEP6aiMeshj:
  104|  2.11k|bool GenVertexNormalsProcess::GenMeshVertexNormals(aiMesh *pMesh, unsigned int meshIndex) {
  105|  2.11k|    if (nullptr != pMesh->mNormals) {
  ------------------
  |  Branch (105:9): [True: 976, False: 1.14k]
  ------------------
  106|    976|        if (!force_) {
  ------------------
  |  Branch (106:13): [True: 976, False: 0]
  ------------------
  107|    976|            return false;
  108|    976|        }
  109|      0|        delete[] pMesh->mNormals;
  110|      0|        pMesh->mNormals = nullptr;
  111|      0|    }
  112|       |
  113|       |    // If the mesh consists of lines and/or points but not of
  114|       |    // triangles or higher-order polygons the normal vectors
  115|       |    // are undefined.
  116|  1.14k|    if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON))) {
  ------------------
  |  Branch (116:9): [True: 578, False: 562]
  ------------------
  117|    578|        ASSIMP_LOG_INFO("Normal vectors are undefined for line and point meshes");
  118|    578|        return false;
  119|    578|    }
  120|       |
  121|       |    // Allocate the array to hold the output normals
  122|    562|    const float qnan = std::numeric_limits<ai_real>::quiet_NaN();
  123|    562|    pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
  124|       |
  125|       |    // Compute per-face normals but store them per-vertex
  126|  17.1k|    for (unsigned int a = 0; a < pMesh->mNumFaces; a++) {
  ------------------
  |  Branch (126:30): [True: 16.6k, False: 562]
  ------------------
  127|  16.6k|        const aiFace &face = pMesh->mFaces[a];
  128|  16.6k|        if (face.mNumIndices < 3) {
  ------------------
  |  Branch (128:13): [True: 0, False: 16.6k]
  ------------------
  129|       |            // either a point or a line -> no normal vector
  130|      0|            for (unsigned int i = 0; i < face.mNumIndices; ++i) {
  ------------------
  |  Branch (130:38): [True: 0, False: 0]
  ------------------
  131|      0|                pMesh->mNormals[face.mIndices[i]] = aiVector3D(qnan);
  132|      0|            }
  133|       |
  134|      0|            continue;
  135|      0|        }
  136|       |
  137|  16.6k|        const aiVector3D *pV1 = &pMesh->mVertices[face.mIndices[0]];
  138|  16.6k|        const aiVector3D *pV2 = &pMesh->mVertices[face.mIndices[1]];
  139|  16.6k|        const aiVector3D *pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices - 1]];
  140|       |        // Boolean XOR - if either but not both of these flags is set, then the winding order has
  141|       |        // changed and the cross product to calculate the normal needs to be reversed
  142|  16.6k|        if (flippedWindingOrder_ != leftHanded_) {
  ------------------
  |  Branch (142:13): [True: 0, False: 16.6k]
  ------------------
  143|      0|            std::swap(pV2, pV3);
  144|      0|        }
  145|  16.6k|        const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe();
  146|       |
  147|  66.4k|        for (unsigned int i = 0; i < face.mNumIndices; ++i) {
  ------------------
  |  Branch (147:34): [True: 49.8k, False: 16.6k]
  ------------------
  148|  49.8k|            pMesh->mNormals[face.mIndices[i]] = vNor;
  149|  49.8k|        }
  150|  16.6k|    }
  151|       |
  152|       |    // Set up a SpatialSort to quickly find all vertices close to a given position
  153|       |    // check whether we can reuse the SpatialSort of a previous step.
  154|    562|    SpatialSort *vertexFinder = nullptr;
  155|    562|    SpatialSort _vertexFinder;
  156|    562|    ai_real posEpsilon = ai_real(1e-5);
  157|    562|    if (shared) {
  ------------------
  |  Branch (157:9): [True: 562, False: 0]
  ------------------
  158|    562|        std::vector<std::pair<SpatialSort, ai_real>> *avf;
  159|    562|        shared->GetProperty(AI_SPP_SPATIAL_SORT, avf);
  ------------------
  |  |  166|    562|#define AI_SPP_SPATIAL_SORT "$Spat"
  ------------------
  160|    562|        if (avf) {
  ------------------
  |  Branch (160:13): [True: 562, False: 0]
  ------------------
  161|    562|            std::pair<SpatialSort, ai_real> &blubb = avf->operator[](meshIndex);
  162|    562|            vertexFinder = &blubb.first;
  163|    562|            posEpsilon = blubb.second;
  164|    562|        }
  165|    562|    }
  166|    562|    if (!vertexFinder) {
  ------------------
  |  Branch (166:9): [True: 0, False: 562]
  ------------------
  167|      0|        _vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof(aiVector3D));
  168|      0|        vertexFinder = &_vertexFinder;
  169|      0|        posEpsilon = ComputePositionEpsilon(pMesh);
  170|      0|    }
  171|    562|    std::vector<unsigned int> verticesFound;
  172|    562|    aiVector3D *pcNew = new aiVector3D[pMesh->mNumVertices];
  173|       |
  174|    562|    if (configMaxAngle >= AI_DEG_TO_RAD(175.f)) {
  ------------------
  |  Branch (174:9): [True: 562, False: 0]
  ------------------
  175|       |        // There is no angle limit. Thus all vertices with positions close
  176|       |        // to each other will receive the same vertex normal. This allows us
  177|       |        // to optimize the whole algorithm a little bit ...
  178|    562|        std::vector<bool> abHad(pMesh->mNumVertices, false);
  179|  48.8k|        for (unsigned int i = 0; i < pMesh->mNumVertices; ++i) {
  ------------------
  |  Branch (179:34): [True: 48.3k, False: 562]
  ------------------
  180|  48.3k|            if (abHad[i]) {
  ------------------
  |  Branch (180:17): [True: 4.95k, False: 43.3k]
  ------------------
  181|  4.95k|                continue;
  182|  4.95k|            }
  183|       |
  184|       |            // Get all vertices that share this one ...
  185|  43.3k|            vertexFinder->FindPositions(pMesh->mVertices[i], posEpsilon, verticesFound);
  186|       |
  187|  43.3k|            aiVector3D pcNor;
  188|  50.0k|            for (unsigned int a = 0; a < verticesFound.size(); ++a) {
  ------------------
  |  Branch (188:38): [True: 6.68k, False: 43.3k]
  ------------------
  189|  6.68k|                const aiVector3D &v = pMesh->mNormals[verticesFound[a]];
  190|  6.68k|                if (is_not_qnan(v.x)) pcNor += v;
  ------------------
  |  Branch (190:21): [True: 5.89k, False: 790]
  ------------------
  191|  6.68k|            }
  192|  43.3k|            pcNor.NormalizeSafe();
  193|       |
  194|       |            // Write the smoothed normal back to all affected normals
  195|  50.0k|            for (unsigned int a = 0; a < verticesFound.size(); ++a) {
  ------------------
  |  Branch (195:38): [True: 6.68k, False: 43.3k]
  ------------------
  196|  6.68k|                unsigned int vidx = verticesFound[a];
  197|  6.68k|                pcNew[vidx] = pcNor;
  198|  6.68k|                abHad[vidx] = true;
  199|  6.68k|            }
  200|  43.3k|        }
  201|    562|    }
  202|       |    // Slower code path if a smooth angle is set. There are many ways to achieve
  203|       |    // the effect, this one is the most straightforward one.
  204|      0|    else {
  205|      0|        const ai_real fLimit = std::cos(configMaxAngle);
  206|      0|        for (unsigned int i = 0; i < pMesh->mNumVertices; ++i) {
  ------------------
  |  Branch (206:34): [True: 0, False: 0]
  ------------------
  207|       |            // Get all vertices that share this one ...
  208|      0|            vertexFinder->FindPositions(pMesh->mVertices[i], posEpsilon, verticesFound);
  209|       |
  210|      0|            aiVector3D vr = pMesh->mNormals[i];
  211|       |
  212|      0|            aiVector3D pcNor;
  213|      0|            for (unsigned int a = 0; a < verticesFound.size(); ++a) {
  ------------------
  |  Branch (213:38): [True: 0, False: 0]
  ------------------
  214|      0|                aiVector3D v = pMesh->mNormals[verticesFound[a]];
  215|       |
  216|       |                // Check whether the angle between the two normals is not too large.
  217|       |                // Skip the angle check on our own normal to avoid false negatives
  218|       |                // (v*v is not guaranteed to be 1.0 for all unit vectors v)
  219|      0|                if (is_not_qnan(v.x) && (verticesFound[a] == i || (v * vr >= fLimit)))
  ------------------
  |  Branch (219:21): [True: 0, False: 0]
  |  Branch (219:42): [True: 0, False: 0]
  |  Branch (219:67): [True: 0, False: 0]
  ------------------
  220|      0|                    pcNor += v;
  221|      0|            }
  222|      0|            pcNew[i] = pcNor.NormalizeSafe();
  223|      0|        }
  224|      0|    }
  225|       |
  226|    562|    delete[] pMesh->mNormals;
  227|    562|    pMesh->mNormals = pcNew;
  228|       |
  229|    562|    return true;
  230|  1.14k|}

_ZN6Assimp27ImproveCacheLocalityProcessC2Ev:
  109|  3.48k|ImproveCacheLocalityProcess::ImproveCacheLocalityProcess() : mConfigCacheDepth(PP_ICL_PTCACHE_SIZE) {
  110|       |    // empty
  111|  3.48k|}
_ZNK6Assimp27ImproveCacheLocalityProcess8IsActiveEj:
  115|  1.43k|bool ImproveCacheLocalityProcess::IsActive(unsigned int pFlags) const {
  116|  1.43k|    return (pFlags & aiProcess_ImproveCacheLocality) != 0;
  117|  1.43k|}
_ZN6Assimp27ImproveCacheLocalityProcess15SetupPropertiesEPKNS_8ImporterE:
  121|  1.43k|void ImproveCacheLocalityProcess::SetupProperties(const Importer *pImp) {
  122|       |    // AI_CONFIG_PP_ICL_PTCACHE_SIZE controls the target cache size for the optimizer
  123|  1.43k|    mConfigCacheDepth = pImp->GetPropertyInteger(AI_CONFIG_PP_ICL_PTCACHE_SIZE, PP_ICL_PTCACHE_SIZE);
  124|  1.43k|}
_ZN6Assimp27ImproveCacheLocalityProcess7ExecuteEP7aiScene:
  128|  1.43k|void ImproveCacheLocalityProcess::Execute(aiScene *pScene) {
  129|  1.43k|    if (!pScene->mNumMeshes) {
  ------------------
  |  Branch (129:9): [True: 159, False: 1.27k]
  ------------------
  130|    159|        ASSIMP_LOG_DEBUG("ImproveCacheLocalityProcess skipped; there are no meshes");
  131|    159|        return;
  132|    159|    }
  133|       |
  134|  1.43k|    ASSIMP_LOG_DEBUG("ImproveCacheLocalityProcess begin");
  135|       |
  136|  1.27k|    float out = 0.f;
  137|  1.27k|    unsigned int numf = 0, numm = 0;
  138|  3.38k|    for (unsigned int a = 0; a < pScene->mNumMeshes; ++a) {
  ------------------
  |  Branch (138:30): [True: 2.11k, False: 1.27k]
  ------------------
  139|  2.11k|        const float res = ProcessMesh(pScene->mMeshes[a], a);
  140|  2.11k|        if (res) {
  ------------------
  |  Branch (140:13): [True: 0, False: 2.11k]
  ------------------
  141|      0|            numf += pScene->mMeshes[a]->mNumFaces;
  142|      0|            out += res;
  143|      0|            ++numm;
  144|      0|        }
  145|  2.11k|    }
  146|  1.27k|    if (!DefaultLogger::isNullLogger()) {
  ------------------
  |  Branch (146:9): [True: 0, False: 1.27k]
  ------------------
  147|      0|        if (numf > 0) {
  ------------------
  |  Branch (147:13): [True: 0, False: 0]
  ------------------
  148|      0|            ASSIMP_LOG_INFO("Cache relevant are ", numm, " meshes (", numf, " faces). Average output ACMR is ", out / numf);
  149|      0|        }
  150|       |        ASSIMP_LOG_DEBUG("ImproveCacheLocalityProcess finished. ");
  151|      0|    }
  152|  1.27k|}
_ZN6Assimp27ImproveCacheLocalityProcess11ProcessMeshEP6aiMeshj:
  156|  2.11k|ai_real ImproveCacheLocalityProcess::ProcessMesh(aiMesh *pMesh, unsigned int meshNum) {
  157|       |    // TODO: rewrite this to use std::vector or boost::shared_array
  158|  2.11k|    ai_assert(nullptr != pMesh);
  159|       |
  160|       |    // Check whether the input data is valid
  161|       |    // - there must be vertices and faces
  162|       |    // - all faces must be triangulated or we can't operate on them
  163|  2.11k|    if (!pMesh->HasFaces() || !pMesh->HasPositions())
  ------------------
  |  Branch (163:9): [True: 0, False: 2.11k]
  |  Branch (163:31): [True: 0, False: 2.11k]
  ------------------
  164|      0|        return static_cast<ai_real>(0.f);
  165|       |
  166|  2.11k|    if (pMesh->mPrimitiveTypes != aiPrimitiveType_TRIANGLE) {
  ------------------
  |  Branch (166:9): [True: 1.32k, False: 796]
  ------------------
  167|  1.32k|        ASSIMP_LOG_ERROR("This algorithm works on triangle meshes only");
  168|  1.32k|        return static_cast<ai_real>(0.f);
  169|  1.32k|    }
  170|       |
  171|    796|    if (pMesh->mNumVertices <= mConfigCacheDepth) {
  ------------------
  |  Branch (171:9): [True: 372, False: 424]
  ------------------
  172|    372|        return static_cast<ai_real>(0.f);
  173|    372|    }
  174|       |
  175|    424|    ai_real fACMR = 3.f;
  176|    424|    const aiFace *const pcEnd = pMesh->mFaces + pMesh->mNumFaces;
  177|       |
  178|       |    // Input ACMR is for logging purposes only
  179|    424|    if (!DefaultLogger::isNullLogger()) {
  ------------------
  |  Branch (179:9): [True: 0, False: 424]
  ------------------
  180|      0|        fACMR = calculateInputACMR(pMesh, pcEnd, mConfigCacheDepth, meshNum);
  181|      0|    }
  182|       |
  183|       |    // first we need to build a vertex-triangle adjacency list
  184|    424|    VertexTriangleAdjacency adj(pMesh->mFaces, pMesh->mNumFaces, pMesh->mNumVertices, true);
  185|       |
  186|       |    // build a list to store per-vertex caching time stamps
  187|    424|    std::vector<unsigned int> piCachingStamps;
  188|    424|    piCachingStamps.resize(pMesh->mNumVertices);
  189|    424|    memset(&piCachingStamps[0], 0x0, pMesh->mNumVertices * sizeof(unsigned int));
  190|       |
  191|       |    // allocate an empty output index buffer. We store the output indices in one large array.
  192|       |    // Since the number of triangles won't change the input faces can be reused. This is how
  193|       |    // we save thousands of redundant mini allocations for aiFace::mIndices
  194|    424|    const unsigned int iIdxCnt = pMesh->mNumFaces * 3;
  195|    424|    std::vector<unsigned int> piIBOutput;
  196|    424|    piIBOutput.resize(iIdxCnt);
  197|    424|    std::vector<unsigned int>::iterator piCSIter = piIBOutput.begin();
  198|       |
  199|       |    // allocate the flag array to hold the information
  200|       |    // whether a face has already been emitted or not
  201|    424|    std::vector<bool> abEmitted(pMesh->mNumFaces, false);
  202|       |
  203|       |    // dead-end vertex index stack
  204|    424|    std::stack<unsigned int, std::vector<unsigned int>> sDeadEndVStack;
  205|       |
  206|       |    // create a copy of the piNumTriPtr buffer
  207|    424|    unsigned int *const piNumTriPtr = adj.mLiveTriangles;
  208|    424|    const std::vector<unsigned int> piNumTriPtrNoModify(piNumTriPtr, piNumTriPtr + pMesh->mNumVertices);
  209|       |
  210|       |    // get the largest number of referenced triangles and allocate the "candidate buffer"
  211|    424|    unsigned int iMaxRefTris = 0;
  212|    424|    {
  213|    424|        const unsigned int *piCur = adj.mLiveTriangles;
  214|    424|        const unsigned int *const piCurEnd = adj.mLiveTriangles + pMesh->mNumVertices;
  215|  12.7k|        for (; piCur != piCurEnd; ++piCur) {
  ------------------
  |  Branch (215:16): [True: 12.3k, False: 424]
  ------------------
  216|  12.3k|            iMaxRefTris = std::max(iMaxRefTris, *piCur);
  217|  12.3k|        }
  218|    424|    }
  219|    424|    ai_assert(iMaxRefTris > 0);
  220|    424|    std::vector<unsigned int> piCandidates;
  221|    424|    piCandidates.resize(iMaxRefTris * 3);
  222|    424|    unsigned int iCacheMisses = 0;
  223|       |
  224|       |    // ...................................................................................
  225|       |    /** PSEUDOCODE for the algorithm
  226|       |
  227|       |        A = Build-Adjacency(I) Vertex-triangle adjacency
  228|       |        L = Get-Triangle-Counts(A) Per-vertex live triangle counts
  229|       |        C = Zero(Vertex-Count(I)) Per-vertex caching time stamps
  230|       |        D = Empty-Stack() Dead-end vertex stack
  231|       |        E = False(Triangle-Count(I)) Per triangle emitted flag
  232|       |        O = Empty-Index-Buffer() Empty output buffer
  233|       |        f = 0 Arbitrary starting vertex
  234|       |        s = k+1, i = 1 Time stamp and cursor
  235|       |        while f >= 0 For all valid fanning vertices
  236|       |            N = Empty-Set() 1-ring of next candidates
  237|       |            for each Triangle t in Neighbors(A, f)
  238|       |                if !Emitted(E,t)
  239|       |                    for each Vertex v in t
  240|       |                        Append(O,v) Output vertex
  241|       |                        Push(D,v) Add to dead-end stack
  242|       |                        Insert(N,v) Register as candidate
  243|       |                        L[v] = L[v]-1 Decrease live triangle count
  244|       |                        if s-C[v] > k If not in cache
  245|       |                            C[v] = s Set time stamp
  246|       |                            s = s+1 Increment time stamp
  247|       |                    E[t] = true Flag triangle as emitted
  248|       |            Select next fanning vertex
  249|       |            f = Get-Next-Vertex(I,i,k,N,C,s,L,D)
  250|       |        return O
  251|       |        */
  252|       |    // ...................................................................................
  253|       |
  254|    424|    int ivdx = 0;
  255|    424|    int ics = 1;
  256|    424|    int iStampCnt = mConfigCacheDepth + 1;
  257|  6.33k|    while (ivdx >= 0) {
  ------------------
  |  Branch (257:12): [True: 5.90k, False: 424]
  ------------------
  258|       |
  259|  5.90k|        unsigned int icnt = piNumTriPtrNoModify[ivdx];
  260|  5.90k|        unsigned int *piList = adj.GetAdjacentTriangles(ivdx);
  261|  5.90k|        std::vector<unsigned int>::iterator piCurCandidate = piCandidates.begin();
  262|       |
  263|       |        // get all triangles in the neighborhood
  264|  37.2k|        for (unsigned int tri = 0; tri < icnt; ++tri) {
  ------------------
  |  Branch (264:36): [True: 31.3k, False: 5.90k]
  ------------------
  265|       |
  266|       |            // if they have not yet been emitted, add them to the output IB
  267|  31.3k|            const unsigned int fidx = *piList++;
  268|  31.3k|            if (!abEmitted[fidx]) {
  ------------------
  |  Branch (268:17): [True: 15.5k, False: 15.7k]
  ------------------
  269|       |
  270|       |                // so iterate through all vertices of the current triangle
  271|  15.5k|                const aiFace *pcFace = &pMesh->mFaces[fidx];
  272|  15.5k|                const unsigned nind = pcFace->mNumIndices;
  273|  62.3k|                for (unsigned ind = 0; ind < nind; ind++) {
  ------------------
  |  Branch (273:40): [True: 46.7k, False: 15.5k]
  ------------------
  274|  46.7k|                    unsigned dp = pcFace->mIndices[ind];
  275|       |
  276|       |                    // the current vertex won't have any free triangles after this step
  277|  46.7k|                    if (ivdx != (int)dp) {
  ------------------
  |  Branch (277:25): [True: 31.1k, False: 15.5k]
  ------------------
  278|       |                        // append the vertex to the dead-end stack
  279|  31.1k|                        sDeadEndVStack.push(dp);
  280|       |
  281|       |                        // register as candidate for the next step
  282|  31.1k|                        *piCurCandidate++ = dp;
  283|       |
  284|       |                        // decrease the per-vertex triangle counts
  285|  31.1k|                        piNumTriPtr[dp]--;
  286|  31.1k|                    }
  287|       |
  288|       |                    // append the vertex to the output index buffer
  289|  46.7k|                    *piCSIter++ = dp;
  290|       |
  291|       |                    // if the vertex is not yet in cache, set its cache count
  292|  46.7k|                    if (iStampCnt - piCachingStamps[dp] > mConfigCacheDepth) {
  ------------------
  |  Branch (292:25): [True: 15.5k, False: 31.2k]
  ------------------
  293|  15.5k|                        piCachingStamps[dp] = iStampCnt++;
  294|  15.5k|                        ++iCacheMisses;
  295|  15.5k|                    }
  296|  46.7k|                }
  297|       |                // flag triangle as emitted
  298|  15.5k|                abEmitted[fidx] = true;
  299|  15.5k|            }
  300|  31.3k|        }
  301|       |
  302|       |        // the vertex has now no living adjacent triangles anymore
  303|  5.90k|        piNumTriPtr[ivdx] = 0;
  304|       |
  305|       |        // get next fanning vertex
  306|  5.90k|        ivdx = -1;
  307|  5.90k|        int max_priority = -1;
  308|  37.0k|        for (std::vector<unsigned int>::iterator piCur = piCandidates.begin(); piCur != piCurCandidate; ++piCur) {
  ------------------
  |  Branch (308:80): [True: 31.1k, False: 5.90k]
  ------------------
  309|  31.1k|            const unsigned int dp = *piCur;
  310|       |
  311|       |            // must have live triangles
  312|  31.1k|            if (piNumTriPtr[dp] > 0) {
  ------------------
  |  Branch (312:17): [True: 21.0k, False: 10.0k]
  ------------------
  313|  21.0k|                int priority = 0;
  314|       |
  315|       |                // will the vertex be in cache, even after fanning occurs?
  316|  21.0k|                unsigned int tmp;
  317|  21.0k|                if ((tmp = iStampCnt - piCachingStamps[dp]) + 2 * piNumTriPtr[dp] <= mConfigCacheDepth) {
  ------------------
  |  Branch (317:21): [True: 11.6k, False: 9.40k]
  ------------------
  318|  11.6k|                    priority = tmp;
  319|  11.6k|                }
  320|       |
  321|       |                // keep best candidate
  322|  21.0k|                if (priority > max_priority) {
  ------------------
  |  Branch (322:21): [True: 5.90k, False: 15.1k]
  ------------------
  323|  5.90k|                    max_priority = priority;
  324|  5.90k|                    ivdx = dp;
  325|  5.90k|                }
  326|  21.0k|            }
  327|  31.1k|        }
  328|       |        // did we reach a dead end?
  329|  5.90k|        if (-1 == ivdx) {
  ------------------
  |  Branch (329:13): [True: 1.46k, False: 4.44k]
  ------------------
  330|       |            // need to get a non-local vertex for which we have a good chance that it is still
  331|       |            // in the cache ...
  332|  32.3k|            while (!sDeadEndVStack.empty()) {
  ------------------
  |  Branch (332:20): [True: 31.1k, False: 1.20k]
  ------------------
  333|  31.1k|                unsigned int iCachedIdx = sDeadEndVStack.top();
  334|  31.1k|                sDeadEndVStack.pop();
  335|  31.1k|                if (piNumTriPtr[iCachedIdx] > 0) {
  ------------------
  |  Branch (335:21): [True: 257, False: 30.9k]
  ------------------
  336|    257|                    ivdx = iCachedIdx;
  337|    257|                    break;
  338|    257|                }
  339|  31.1k|            }
  340|       |
  341|  1.46k|            if (-1 == ivdx) {
  ------------------
  |  Branch (341:17): [True: 1.20k, False: 257]
  ------------------
  342|       |                // well, there isn't such a vertex. Simply get the next vertex in input order and
  343|       |                // hope it is not too bad ...
  344|  12.3k|                while (ics < (int)pMesh->mNumVertices) {
  ------------------
  |  Branch (344:24): [True: 11.9k, False: 424]
  ------------------
  345|  11.9k|                    ++ics;
  346|  11.9k|                    if (piNumTriPtr[ics] > 0) {
  ------------------
  |  Branch (346:25): [True: 780, False: 11.1k]
  ------------------
  347|    780|                        ivdx = ics;
  348|    780|                        break;
  349|    780|                    }
  350|  11.9k|                }
  351|  1.20k|            }
  352|  1.46k|        }
  353|  5.90k|    }
  354|    424|    ai_real fACMR2 = 0.0f;
  355|    424|    if (!DefaultLogger::isNullLogger()) {
  ------------------
  |  Branch (355:9): [True: 0, False: 424]
  ------------------
  356|      0|        fACMR2 = static_cast<ai_real>(iCacheMisses / pMesh->mNumFaces);
  357|      0|        const ai_real averageACMR = ((fACMR - fACMR2) / fACMR) * 100.f;
  358|       |        // very intense verbose logging ... prepare for much text if there are many meshes
  359|      0|        if (DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) {
  ------------------
  |  Branch (359:13): [True: 0, False: 0]
  ------------------
  360|      0|            ASSIMP_LOG_VERBOSE_DEBUG("Mesh ", meshNum, "| ACMR in: ", fACMR, " out: ", fACMR2, " | average ACMR ", averageACMR);
  361|      0|        }
  362|      0|        fACMR2 *= pMesh->mNumFaces;
  363|      0|    }
  364|       |
  365|       |    // sort the output index buffer back to the input array
  366|    424|    piCSIter = piIBOutput.begin();
  367|  16.0k|    for (aiFace *pcFace = pMesh->mFaces; pcFace != pcEnd; ++pcFace) {
  ------------------
  |  Branch (367:42): [True: 15.5k, False: 424]
  ------------------
  368|  15.5k|        unsigned nind = pcFace->mNumIndices;
  369|  15.5k|        unsigned *ind = pcFace->mIndices;
  370|  15.5k|        if (nind > 0)
  ------------------
  |  Branch (370:13): [True: 15.5k, False: 0]
  ------------------
  371|  15.5k|            ind[0] = *piCSIter++;
  372|  15.5k|        if (nind > 1)
  ------------------
  |  Branch (372:13): [True: 15.5k, False: 0]
  ------------------
  373|  15.5k|            ind[1] = *piCSIter++;
  374|  15.5k|        if (nind > 2)
  ------------------
  |  Branch (374:13): [True: 15.5k, False: 0]
  ------------------
  375|  15.5k|            ind[2] = *piCSIter++;
  376|  15.5k|    }
  377|       |
  378|    424|    return fACMR2;
  379|    796|}

_ZNK6Assimp19JoinVerticesProcess8IsActiveEj:
   63|  1.43k|bool JoinVerticesProcess::IsActive( unsigned int pFlags) const {
   64|  1.43k|    return (pFlags & aiProcess_JoinIdenticalVertices) != 0;
   65|  1.43k|}
_ZN6Assimp19JoinVerticesProcess7ExecuteEP7aiScene:
   68|  1.43k|void JoinVerticesProcess::Execute( aiScene* pScene) {
   69|  1.43k|    ASSIMP_LOG_DEBUG("JoinVerticesProcess begin");
   70|       |
   71|       |    // get the total number of vertices BEFORE the step is executed
   72|  1.43k|    int iNumOldVertices = 0;
   73|  1.43k|    if (!DefaultLogger::isNullLogger()) {
  ------------------
  |  Branch (73:9): [True: 0, False: 1.43k]
  ------------------
   74|      0|        for( unsigned int a = 0; a < pScene->mNumMeshes; a++)   {
  ------------------
  |  Branch (74:34): [True: 0, False: 0]
  ------------------
   75|      0|            iNumOldVertices +=  pScene->mMeshes[a]->mNumVertices;
   76|      0|        }
   77|      0|    }
   78|       |
   79|       |    // execute the step
   80|  1.43k|    int iNumVertices = 0;
   81|  3.54k|    for( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
  ------------------
  |  Branch (81:30): [True: 2.11k, False: 1.43k]
  ------------------
   82|  2.11k|        iNumVertices += ProcessMesh( pScene->mMeshes[a],a);
   83|  2.11k|    }
   84|       |
   85|  1.43k|    pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
   86|       |
   87|       |    // if logging is active, print detailed statistics
   88|  1.43k|    if (!DefaultLogger::isNullLogger()) {
  ------------------
  |  Branch (88:9): [True: 0, False: 1.43k]
  ------------------
   89|      0|        if (iNumOldVertices == iNumVertices) {
  ------------------
  |  Branch (89:13): [True: 0, False: 0]
  ------------------
   90|      0|            ASSIMP_LOG_DEBUG("JoinVerticesProcess finished ");
   91|      0|            return;
   92|      0|        }
   93|       |
   94|       |        // Show statistics
   95|      0|        ASSIMP_LOG_INFO("JoinVerticesProcess finished | Verts in: ", iNumOldVertices,
   96|      0|            " out: ", iNumVertices, " | ~",
   97|      0|            ((iNumOldVertices - iNumVertices) / (float)iNumOldVertices) * 100.f );
   98|      0|    }
   99|  1.43k|}
_ZN6Assimp19JoinVerticesProcess11ProcessMeshEP6aiMeshj:
  225|  2.11k|int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) {
  226|  2.11k|    static_assert( AI_MAX_NUMBER_OF_COLOR_SETS    == 8, "AI_MAX_NUMBER_OF_COLOR_SETS    == 8");
  227|  2.11k|	static_assert( AI_MAX_NUMBER_OF_TEXTURECOORDS == 8, "AI_MAX_NUMBER_OF_TEXTURECOORDS == 8");
  228|       |
  229|       |    // Return early if we don't have any positions
  230|  2.11k|    if (!pMesh->HasPositions() || !pMesh->HasFaces()) {
  ------------------
  |  Branch (230:9): [True: 0, False: 2.11k]
  |  Branch (230:35): [True: 0, False: 2.11k]
  ------------------
  231|      0|        return 0;
  232|      0|    }
  233|       |
  234|       |    // We should care only about used vertices, not all of them
  235|       |    // (this can happen due to original file vertices buffer being used by
  236|       |    // multiple meshes)
  237|  2.11k|    std::vector<bool> usedVertexIndicesMask;
  238|  2.11k|    usedVertexIndicesMask.resize(pMesh->mNumVertices, false);
  239|  32.7k|    for (unsigned int a = 0; a < pMesh->mNumFaces; a++) {
  ------------------
  |  Branch (239:30): [True: 30.6k, False: 2.11k]
  ------------------
  240|  30.6k|        aiFace& face = pMesh->mFaces[a];
  241|   106k|        for (unsigned int b = 0; b < face.mNumIndices; b++) {
  ------------------
  |  Branch (241:34): [True: 75.9k, False: 30.6k]
  ------------------
  242|  75.9k|            usedVertexIndicesMask[face.mIndices[b]] = true;
  243|  75.9k|        }
  244|  30.6k|    }
  245|       |
  246|       |    // We'll never have more vertices afterwards.
  247|  2.11k|    std::vector<int> uniqueVertices;
  248|       |
  249|       |    // For each vertex the index of the vertex it was replaced by.
  250|       |    // Since the maximal number of vertices is 2^31-1, the most significand bit can be used to mark
  251|       |    //  whether a new vertex was created for the index (true) or if it was replaced by an existing
  252|       |    //  unique vertex (false). This saves an additional std::vector<bool> and greatly enhances
  253|       |    //  branching performance.
  254|  2.11k|    static_assert(AI_MAX_VERTICES == 0x7fffffff, "AI_MAX_VERTICES == 0x7fffffff");
  255|  2.11k|    std::vector<unsigned int> replaceIndex( pMesh->mNumVertices, 0xffffffff);
  256|       |
  257|       |    // Run an optimized code path if we don't have multiple UVs or vertex colors.
  258|       |    // This should yield false in more than 99% of all imports ...
  259|  2.11k|    const bool hasAnimMeshes = pMesh->mNumAnimMeshes > 0;
  260|       |
  261|       |    // We'll never have more vertices afterwards.
  262|  2.11k|    std::vector<std::vector<int>> uniqueAnimatedVertices;
  263|  2.11k|    if (hasAnimMeshes) {
  ------------------
  |  Branch (263:9): [True: 0, False: 2.11k]
  ------------------
  264|      0|        uniqueAnimatedVertices.resize(pMesh->mNumAnimMeshes);
  265|      0|        for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) {
  ------------------
  |  Branch (265:46): [True: 0, False: 0]
  ------------------
  266|      0|            uniqueAnimatedVertices[animMeshIndex].reserve(pMesh->mNumVertices);
  267|      0|        }
  268|      0|    }
  269|       |    // a map that maps a vertex to its new index
  270|  2.11k|    std::unordered_map<Vertex, int, HashVertex, CompareVerticesAlmostEqual> vertex2Index = {};
  271|       |    // we can not end up with more vertices than we started with
  272|       |    // Now check each vertex if it brings something new to the table
  273|  2.11k|    int newIndex = 0;
  274|  74.9k|    for( unsigned int a = 0; a < pMesh->mNumVertices; a++)  {
  ------------------
  |  Branch (274:30): [True: 72.8k, False: 2.11k]
  ------------------
  275|       |        // if the vertex is unused Do nothing
  276|  72.8k|        if (!usedVertexIndicesMask[a]) {
  ------------------
  |  Branch (276:13): [True: 370, False: 72.5k]
  ------------------
  277|    370|            continue;
  278|    370|        }
  279|       |        // collect the vertex data
  280|  72.5k|        Vertex v(pMesh,a);
  281|       |        // is the vertex already in the map?
  282|  72.5k|        auto it = vertex2Index.find(v);
  283|       |        // if the vertex is not in the map then it is a new vertex add it.
  284|  72.5k|        if (it == vertex2Index.end()) {
  ------------------
  |  Branch (284:13): [True: 22.4k, False: 50.0k]
  ------------------
  285|       |            // this is a new vertex give it a new index
  286|  22.4k|            vertex2Index.emplace(v, newIndex);
  287|       |            // keep track of its index and increment 1
  288|  22.4k|            replaceIndex[a] = newIndex++;
  289|       |            // add the vertex to the unique vertices
  290|  22.4k|            uniqueVertices.push_back(a);
  291|  22.4k|            if (hasAnimMeshes) {
  ------------------
  |  Branch (291:17): [True: 0, False: 22.4k]
  ------------------
  292|      0|                for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) {
  ------------------
  |  Branch (292:54): [True: 0, False: 0]
  ------------------
  293|      0|                    uniqueAnimatedVertices[animMeshIndex].emplace_back(a);
  294|      0|                }
  295|      0|            }
  296|  50.0k|        } else{
  297|       |            // if the vertex is already there just find the replace index that is appropriate to it
  298|       |			// mark it with JOINED_VERTICES_MARK
  299|  50.0k|            replaceIndex[a] = it->second | JOINED_VERTICES_MARK;
  300|  50.0k|        }
  301|  72.5k|    }
  302|       |
  303|  2.11k|    if (!DefaultLogger::isNullLogger() && DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE)    {
  ------------------
  |  Branch (303:9): [True: 0, False: 2.11k]
  |  Branch (303:43): [True: 0, False: 0]
  ------------------
  304|      0|        ASSIMP_LOG_VERBOSE_DEBUG(
  ------------------
  |  Branch (304:9): [True: 0, False: 0]
  ------------------
  305|      0|            "Mesh ",meshIndex,
  306|      0|            " (",
  307|      0|            (pMesh->mName.length ? pMesh->mName.data : "unnamed"),
  308|      0|            ") | Verts in: ",pMesh->mNumVertices,
  309|      0|            " out: ",
  310|      0|            uniqueVertices.size(),
  311|      0|            " | ~",
  312|      0|            ((pMesh->mNumVertices - uniqueVertices.size()) / (float)pMesh->mNumVertices) * 100.f,
  313|      0|            "%"
  314|      0|        );
  315|      0|    }
  316|       |
  317|  2.11k|    updateXMeshVertices(pMesh, uniqueVertices);
  318|  2.11k|    if (hasAnimMeshes) {
  ------------------
  |  Branch (318:9): [True: 0, False: 2.11k]
  ------------------
  319|      0|        for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) {
  ------------------
  |  Branch (319:46): [True: 0, False: 0]
  ------------------
  320|      0|            updateXMeshVertices(pMesh->mAnimMeshes[animMeshIndex], uniqueAnimatedVertices[animMeshIndex]);
  321|      0|        }
  322|      0|    }
  323|       |
  324|       |    // adjust the indices in all faces
  325|  32.7k|    for( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
  ------------------
  |  Branch (325:30): [True: 30.6k, False: 2.11k]
  ------------------
  326|  30.6k|        aiFace& face = pMesh->mFaces[a];
  327|   106k|        for( unsigned int b = 0; b < face.mNumIndices; b++) {
  ------------------
  |  Branch (327:34): [True: 75.9k, False: 30.6k]
  ------------------
  328|  75.9k|            face.mIndices[b] = replaceIndex[face.mIndices[b]] & ~JOINED_VERTICES_MARK;
  329|  75.9k|        }
  330|  30.6k|    }
  331|       |
  332|       |    // adjust bone vertex weights.
  333|  4.07k|    for( int a = 0; a < (int)pMesh->mNumBones; a++) {
  ------------------
  |  Branch (333:21): [True: 1.95k, False: 2.11k]
  ------------------
  334|  1.95k|        aiBone* bone = pMesh->mBones[a];
  335|  1.95k|        std::vector<aiVertexWeight> newWeights;
  336|  1.95k|        newWeights.reserve( bone->mNumWeights);
  337|       |
  338|  1.95k|        if (nullptr != bone->mWeights) {
  ------------------
  |  Branch (338:13): [True: 1.95k, False: 0]
  ------------------
  339|  7.70k|            for ( unsigned int b = 0; b < bone->mNumWeights; b++ ) {
  ------------------
  |  Branch (339:39): [True: 5.74k, False: 1.95k]
  ------------------
  340|  5.74k|                const aiVertexWeight& ow = bone->mWeights[ b ];
  341|       |                // if the vertex is a unique one, translate it
  342|       |				// filter out joined vertices by JOINED_VERTICES_MARK.
  343|  5.74k|                if ( !( replaceIndex[ ow.mVertexId ] & JOINED_VERTICES_MARK ) ) {
  ------------------
  |  Branch (343:22): [True: 5.05k, False: 688]
  ------------------
  344|  5.05k|                    aiVertexWeight nw;
  345|  5.05k|                    nw.mVertexId = replaceIndex[ ow.mVertexId ];
  346|  5.05k|                    nw.mWeight = ow.mWeight;
  347|  5.05k|                    newWeights.push_back( nw );
  348|  5.05k|                }
  349|  5.74k|            }
  350|  1.95k|        } else {
  351|      0|            ASSIMP_LOG_ERROR( "X-Export: aiBone shall contain weights, but pointer to them is nullptr." );
  352|      0|        }
  353|       |
  354|  1.95k|        if (newWeights.size() > 0) {
  ------------------
  |  Branch (354:13): [True: 1.90k, False: 50]
  ------------------
  355|       |            // kill the old and replace them with the translated weights
  356|  1.90k|            delete [] bone->mWeights;
  357|  1.90k|            bone->mNumWeights = (unsigned int)newWeights.size();
  358|       |
  359|  1.90k|            bone->mWeights = new aiVertexWeight[bone->mNumWeights];
  360|  1.90k|            memcpy( bone->mWeights, &newWeights[0], bone->mNumWeights * sizeof( aiVertexWeight));
  361|  1.90k|        }
  362|  1.95k|    }
  363|  2.11k|    return pMesh->mNumVertices;
  364|  2.11k|}
JoinVerticesProcess.cpp:_ZNK12_GLOBAL__N_110HashVertexclERKN6Assimp6VertexE:
  151|  92.8k|    size_t operator () (const Vertex & v) const {
  152|  92.8k|        size_t hash = 0;
  153|       |
  154|  92.8k|        hash_combine(hash, v.position.x);
  155|  92.8k|        hash_combine(hash, v.position.y);
  156|  92.8k|        hash_combine(hash, v.position.z);
  157|       |
  158|  92.8k|        return hash;
  159|  92.8k|    }
JoinVerticesProcess.cpp:_ZNK12_GLOBAL__N_110HashVertex12hash_combineERmRKf:
  146|   278k|    inline void hash_combine(std::size_t& seed, const ai_real& v) const {
  147|   278k|        std::hash<ai_real> hasher;
  148|   278k|        seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
  149|   278k|    }
JoinVerticesProcess.cpp:_ZNK12_GLOBAL__N_126CompareVerticesAlmostEqualclERKN6Assimp6VertexES4_:
  104|  55.6k|    bool operator () (const Vertex & a, const Vertex & b) const {
  105|  55.6k|        static const float epsilon = 1e-5f;
  106|  55.6k|        static const float squareEpsilon = epsilon * epsilon;
  107|       |
  108|  55.6k|        if ((a.position - b.position).SquareLength() > squareEpsilon) {
  ------------------
  |  Branch (108:13): [True: 0, False: 55.6k]
  ------------------
  109|      0|            return false;
  110|      0|        }
  111|       |
  112|       |        // We just test the other attributes even if they're not present in the mesh.
  113|       |        // In this case they're initialized to 0 so the comparison succeeds.
  114|       |        // By this method the non-present attributes are effectively ignored in the comparison.
  115|       |
  116|  55.6k|        if ((a.normal - b.normal).SquareLength() > squareEpsilon) {
  ------------------
  |  Branch (116:13): [True: 1.31k, False: 54.3k]
  ------------------
  117|  1.31k|            return false;
  118|  1.31k|        }
  119|       |
  120|  54.3k|        if ((a.tangent - b.tangent).SquareLength() > squareEpsilon) {
  ------------------
  |  Branch (120:13): [True: 2.77k, False: 51.5k]
  ------------------
  121|  2.77k|            return false;
  122|  2.77k|        }
  123|       |
  124|  51.5k|        if ((a.bitangent - b.bitangent).SquareLength() > squareEpsilon) {
  ------------------
  |  Branch (124:13): [True: 909, False: 50.6k]
  ------------------
  125|    909|            return false;
  126|    909|        }
  127|       |
  128|   452k|        for (uint32_t i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; i ++) {
  ------------------
  |  Branch (128:30): [True: 402k, False: 50.1k]
  ------------------
  129|   402k|            if ((a.texcoords[i] - b.texcoords[i]).SquareLength() > squareEpsilon) {
  ------------------
  |  Branch (129:17): [True: 449, False: 401k]
  ------------------
  130|    449|                return false;
  131|    449|            }
  132|   402k|        }
  133|       |
  134|   450k|        for (uint32_t i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; i ++) {
  ------------------
  |  Branch (134:30): [True: 400k, False: 50.0k]
  ------------------
  135|   400k|            if (GetColorDifference(a.colors[i], b.colors[i]) > squareEpsilon) {
  ------------------
  |  Branch (135:17): [True: 135, False: 400k]
  ------------------
  136|    135|                return false;
  137|    135|            }
  138|   400k|        }
  139|       |
  140|       |        // If reached this point, they are ~equal
  141|  50.0k|        return true;
  142|  50.1k|    }
JoinVerticesProcess.cpp:_ZN12_GLOBAL__N_119updateXMeshVerticesI6aiMeshEEvPT_RNSt3__16vectorIiNS4_9allocatorIiEEEE:
  163|  2.11k|void updateXMeshVertices(XMesh *pMesh, std::vector<int> &uniqueVertices) {
  164|       |    // replace vertex data with the unique data sets
  165|  2.11k|    pMesh->mNumVertices = (unsigned int)uniqueVertices.size();
  166|       |
  167|       |    // ----------------------------------------------------------------------------
  168|       |    // NOTE - we're *not* calling Vertex::SortBack() because it would check for
  169|       |    // presence of every single vertex component once PER VERTEX. And our CPU
  170|       |    // dislikes branches, even if they're easily predictable.
  171|       |    // ----------------------------------------------------------------------------
  172|       |
  173|       |    // Position, if present (check made for aiAnimMesh)
  174|  2.11k|    if (pMesh->mVertices) {
  ------------------
  |  Branch (174:9): [True: 2.11k, False: 0]
  ------------------
  175|  2.11k|        std::unique_ptr<aiVector3D[]> oldVertices(pMesh->mVertices);
  176|  2.11k|        pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
  177|  24.5k|        for (unsigned int a = 0; a < pMesh->mNumVertices; a++)
  ------------------
  |  Branch (177:34): [True: 22.4k, False: 2.11k]
  ------------------
  178|  22.4k|            pMesh->mVertices[a] = oldVertices[uniqueVertices[a]];
  179|  2.11k|    }
  180|       |
  181|       |    // Normals, if present
  182|  2.11k|    if (pMesh->mNormals) {
  ------------------
  |  Branch (182:9): [True: 1.53k, False: 578]
  ------------------
  183|  1.53k|        std::unique_ptr<aiVector3D[]> oldNormals(pMesh->mNormals);
  184|  1.53k|        pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
  185|  19.4k|        for (unsigned int a = 0; a < pMesh->mNumVertices; a++)
  ------------------
  |  Branch (185:34): [True: 17.8k, False: 1.53k]
  ------------------
  186|  17.8k|            pMesh->mNormals[a] = oldNormals[uniqueVertices[a]];
  187|  1.53k|    }
  188|       |    // Tangents, if present
  189|  2.11k|    if (pMesh->mTangents) {
  ------------------
  |  Branch (189:9): [True: 264, False: 1.85k]
  ------------------
  190|    264|        std::unique_ptr<aiVector3D[]> oldTangents(pMesh->mTangents);
  191|    264|        pMesh->mTangents = new aiVector3D[pMesh->mNumVertices];
  192|  3.50k|        for (unsigned int a = 0; a < pMesh->mNumVertices; a++)
  ------------------
  |  Branch (192:34): [True: 3.23k, False: 264]
  ------------------
  193|  3.23k|            pMesh->mTangents[a] = oldTangents[uniqueVertices[a]];
  194|    264|    }
  195|       |    // Bitangents as well
  196|  2.11k|    if (pMesh->mBitangents) {
  ------------------
  |  Branch (196:9): [True: 264, False: 1.85k]
  ------------------
  197|    264|        std::unique_ptr<aiVector3D[]> oldBitangents(pMesh->mBitangents);
  198|    264|        pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices];
  199|  3.50k|        for (unsigned int a = 0; a < pMesh->mNumVertices; a++)
  ------------------
  |  Branch (199:34): [True: 3.23k, False: 264]
  ------------------
  200|  3.23k|            pMesh->mBitangents[a] = oldBitangents[uniqueVertices[a]];
  201|    264|    }
  202|       |    // Vertex colors
  203|  2.38k|    for (unsigned int a = 0; pMesh->HasVertexColors(a); a++) {
  ------------------
  |  Branch (203:30): [True: 272, False: 2.11k]
  ------------------
  204|    272|        std::unique_ptr<aiColor4D[]> oldColors(pMesh->mColors[a]);
  205|    272|        pMesh->mColors[a] = new aiColor4D[pMesh->mNumVertices];
  206|  1.43k|        for (unsigned int b = 0; b < pMesh->mNumVertices; b++)
  ------------------
  |  Branch (206:34): [True: 1.16k, False: 272]
  ------------------
  207|  1.16k|            pMesh->mColors[a][b] = oldColors[uniqueVertices[b]];
  208|    272|    }
  209|       |    // Texture coords
  210|  2.58k|    for (unsigned int a = 0; pMesh->HasTextureCoords(a); a++) {
  ------------------
  |  Branch (210:30): [True: 471, False: 2.11k]
  ------------------
  211|    471|        std::unique_ptr<aiVector3D[]> oldTextureCoords(pMesh->mTextureCoords[a]);
  212|    471|        pMesh->mTextureCoords[a] = new aiVector3D[pMesh->mNumVertices];
  213|  4.77k|        for (unsigned int b = 0; b < pMesh->mNumVertices; b++)
  ------------------
  |  Branch (213:34): [True: 4.30k, False: 471]
  ------------------
  214|  4.30k|            pMesh->mTextureCoords[a][b] = oldTextureCoords[uniqueVertices[b]];
  215|    471|    }
  216|  2.11k|}

_ZN6Assimp19JoinVerticesProcessC2Ev:
   67|  3.48k|    JoinVerticesProcess() = default;

_ZN6Assimp23LimitBoneWeightsProcessC2Ev:
   57|  3.48k|        mMaxWeights(AI_LMW_MAX_WEIGHTS), mRemoveEmptyBones(true) {
   58|       |    // empty
   59|  3.48k|}
_ZNK6Assimp23LimitBoneWeightsProcess8IsActiveEj:
   63|  1.43k|bool LimitBoneWeightsProcess::IsActive( unsigned int pFlags) const {
   64|  1.43k|    return (pFlags & aiProcess_LimitBoneWeights) != 0;
   65|  1.43k|}
_ZN6Assimp23LimitBoneWeightsProcess7ExecuteEP7aiScene:
   69|  1.43k|void LimitBoneWeightsProcess::Execute( aiScene* pScene) {
   70|  1.43k|    ai_assert(pScene != nullptr);
   71|       |
   72|  1.43k|    ASSIMP_LOG_DEBUG("LimitBoneWeightsProcess begin");
   73|       |
   74|  3.54k|    for (unsigned int m = 0; m < pScene->mNumMeshes; ++m) {
  ------------------
  |  Branch (74:30): [True: 2.11k, False: 1.43k]
  ------------------
   75|  2.11k|        ProcessMesh(pScene->mMeshes[m]);
   76|  2.11k|    }
   77|       |
   78|       |    ASSIMP_LOG_DEBUG("LimitBoneWeightsProcess end");
   79|  1.43k|}
_ZN6Assimp23LimitBoneWeightsProcess15SetupPropertiesEPKNS_8ImporterE:
   83|  1.43k|void LimitBoneWeightsProcess::SetupProperties(const Importer* pImp) {
   84|  1.43k|    this->mMaxWeights = pImp->GetPropertyInteger(AI_CONFIG_PP_LBW_MAX_WEIGHTS,AI_LMW_MAX_WEIGHTS);
   85|       |    this->mRemoveEmptyBones = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, 1) != 0;
   86|  1.43k|}
_ZN6Assimp23LimitBoneWeightsProcess11ProcessMeshEP6aiMesh:
  107|  2.11k|void LimitBoneWeightsProcess::ProcessMesh(aiMesh* pMesh) {
  108|  2.11k|    if (!pMesh->HasBones())
  ------------------
  |  Branch (108:9): [True: 1.88k, False: 230]
  ------------------
  109|  1.88k|        return;
  110|       |
  111|       |    // collect all bone weights per vertex
  112|    230|    typedef SmallVector<Weight,8> VertexWeightArray;
  113|    230|    typedef std::vector<VertexWeightArray> WeightsPerVertex;
  114|    230|    WeightsPerVertex vertexWeights(pMesh->mNumVertices);
  115|    230|    size_t maxVertexWeights = 0;
  116|       |
  117|  2.18k|    for (unsigned int b = 0; b < pMesh->mNumBones; ++b) {
  ------------------
  |  Branch (117:30): [True: 1.95k, False: 230]
  ------------------
  118|  1.95k|        const aiBone* bone = pMesh->mBones[b];
  119|  7.07k|        for (unsigned int w = 0; w < bone->mNumWeights; ++w) {
  ------------------
  |  Branch (119:34): [True: 5.11k, False: 1.95k]
  ------------------
  120|  5.11k|            const aiVertexWeight& vw = bone->mWeights[w];
  121|       |
  122|  5.11k|            if (vertexWeights.size() <= vw.mVertexId)
  ------------------
  |  Branch (122:17): [True: 26, False: 5.09k]
  ------------------
  123|     26|                continue;
  124|       |
  125|  5.09k|            vertexWeights[vw.mVertexId].push_back(Weight(b, vw.mWeight));
  126|  5.09k|            maxVertexWeights = std::max(maxVertexWeights, vertexWeights[vw.mVertexId].size());
  127|  5.09k|        }
  128|  1.95k|    }
  129|       |
  130|    230|    if (maxVertexWeights <= mMaxWeights)
  ------------------
  |  Branch (130:9): [True: 24, False: 206]
  ------------------
  131|     24|        return;
  132|       |
  133|    206|    unsigned int removed = 0, old_bones = pMesh->mNumBones;
  134|       |
  135|       |    // now cut the weight count if it exceeds the maximum
  136|    901|    for (WeightsPerVertex::iterator vit = vertexWeights.begin(); vit != vertexWeights.end(); ++vit) {
  ------------------
  |  Branch (136:66): [True: 695, False: 206]
  ------------------
  137|    695|        if (vit->size() <= mMaxWeights)
  ------------------
  |  Branch (137:13): [True: 122, False: 573]
  ------------------
  138|    122|            continue;
  139|       |
  140|       |        // more than the defined maximum -> first sort by weight in descending order. That's
  141|       |        // why we defined the < operator in such a weird way.
  142|    573|        std::sort(vit->begin(), vit->end());
  143|       |
  144|       |        // now kill everything beyond the maximum count
  145|    573|        unsigned int m = static_cast<unsigned int>(vit->size());
  146|    573|        vit->resize(mMaxWeights);
  147|    573|        removed += static_cast<unsigned int>(m - vit->size());
  148|       |
  149|       |        // and renormalize the weights
  150|    573|        float sum = 0.0f;
  151|  2.86k|        for(const Weight* it = vit->begin(); it != vit->end(); ++it) {
  ------------------
  |  Branch (151:46): [True: 2.29k, False: 573]
  ------------------
  152|  2.29k|            sum += it->mWeight;
  153|  2.29k|        }
  154|    573|        if (0.0f != sum) {
  ------------------
  |  Branch (154:13): [True: 538, False: 35]
  ------------------
  155|    538|            const float invSum = 1.0f / sum;
  156|  2.69k|            for(Weight* it = vit->begin(); it != vit->end(); ++it) {
  ------------------
  |  Branch (156:44): [True: 2.15k, False: 538]
  ------------------
  157|  2.15k|                it->mWeight *= invSum;
  158|  2.15k|            }
  159|    538|        }
  160|    573|    }
  161|       |
  162|       |    // clear weight count for all bone
  163|  2.09k|    for (unsigned int a = 0; a < pMesh->mNumBones; ++a) {
  ------------------
  |  Branch (163:30): [True: 1.89k, False: 206]
  ------------------
  164|  1.89k|        pMesh->mBones[a]->mNumWeights = 0;
  165|  1.89k|    }
  166|       |
  167|       |    // rebuild the vertex weight array for all bones
  168|    901|    for (unsigned int a = 0; a < vertexWeights.size(); ++a) {
  ------------------
  |  Branch (168:30): [True: 695, False: 206]
  ------------------
  169|    695|        const VertexWeightArray& vw = vertexWeights[a];
  170|  3.23k|        for (const Weight* it = vw.begin(); it != vw.end(); ++it) {
  ------------------
  |  Branch (170:45): [True: 2.54k, False: 695]
  ------------------
  171|  2.54k|            aiBone* bone = pMesh->mBones[it->mBone];
  172|  2.54k|            bone->mWeights[bone->mNumWeights++] = aiVertexWeight(a, it->mWeight);
  173|  2.54k|        }
  174|    695|    }
  175|       |
  176|       |    // remove empty bones
  177|    206|    if (mRemoveEmptyBones) {
  ------------------
  |  Branch (177:9): [True: 206, False: 0]
  ------------------
  178|    206|        pMesh->mNumBones = removeEmptyBones(pMesh);
  179|    206|    }
  180|       |
  181|    206|    if (!DefaultLogger::isNullLogger()) {
  ------------------
  |  Branch (181:9): [True: 0, False: 206]
  ------------------
  182|       |        ASSIMP_LOG_INFO("Removed ", removed, " weights. Input bones: ", old_bones, ". Output bones: ", pMesh->mNumBones);
  183|      0|    }
  184|    206|}
LimitBoneWeightsProcess.cpp:_ZN6AssimpL16removeEmptyBonesEP6aiMesh:
   89|    206|static unsigned int removeEmptyBones(aiMesh *pMesh) {
   90|    206|    ai_assert(pMesh != nullptr);
   91|       |
   92|    206|    unsigned int writeBone = 0;
   93|  2.09k|    for (unsigned int readBone = 0; readBone< pMesh->mNumBones; ++readBone) {
  ------------------
  |  Branch (93:37): [True: 1.89k, False: 206]
  ------------------
   94|  1.89k|        aiBone* bone = pMesh->mBones[readBone];
   95|  1.89k|        if (bone->mNumWeights > 0) {
  ------------------
  |  Branch (95:13): [True: 862, False: 1.03k]
  ------------------
   96|    862|            pMesh->mBones[writeBone++] = bone;
   97|  1.03k|        } else {
   98|  1.03k|            delete bone;
   99|  1.03k|        }
  100|  1.89k|    }
  101|       |
  102|    206|    return writeBone;
  103|    206|}

_ZN6Assimp23LimitBoneWeightsProcess6WeightC2Ev:
  116|  10.1k|        : mBone(0)
  117|  10.1k|        , mWeight(0.0f) {
  118|       |            // empty
  119|  10.1k|        }
_ZN6Assimp23LimitBoneWeightsProcess6WeightC2Ejf:
  122|  5.09k|        : mBone(pBone)
  123|  5.09k|        , mWeight(pWeight) {
  124|       |            // empty
  125|  5.09k|        }
_ZNK6Assimp23LimitBoneWeightsProcess6WeightltERKS1_:
  128|  9.11k|        bool operator < (const Weight& pWeight) const {
  129|  9.11k|            return mWeight > pWeight.mWeight;
  130|  9.11k|        }

_ZN6Assimp20OptimizeGraphProcessC2Ev:
   77|  3.48k|		count_merged() {
   78|       |	// empty
   79|  3.48k|}
_ZNK6Assimp20OptimizeGraphProcess8IsActiveEj:
   83|  1.48k|bool OptimizeGraphProcess::IsActive(unsigned int pFlags) const {
   84|  1.48k|	return (0 != (pFlags & aiProcess_OptimizeGraph));
   85|  1.48k|}

_ZN6Assimp20OptimizeGraphProcessD2Ev:
   76|  3.48k|    ~OptimizeGraphProcess() override = default;

_ZN6Assimp21OptimizeMeshesProcessC2Ev:
   66|  3.48k|    , pts(false)
   67|  3.48k|    , max_verts( NotSet )
   68|  3.48k|    , max_faces( NotSet ) {
   69|       |    // empty
   70|  3.48k|}
_ZNK6Assimp21OptimizeMeshesProcess8IsActiveEj:
   75|  1.43k|{
   76|       |    // Our behaviour needs to be different if the SortByPType or SplitLargeMeshes
   77|       |    // steps are active. Thus we need to query their flags here and store the
   78|       |    // information, although we're breaking const-correctness.
   79|       |    // That's a serious design flaw, consider redesign.
   80|  1.43k|    if( 0 != (pFlags & aiProcess_OptimizeMeshes) ) {
  ------------------
  |  Branch (80:9): [True: 0, False: 1.43k]
  ------------------
   81|      0|        pts = (0 != (pFlags & aiProcess_SortByPType));
   82|      0|        max_verts = ( 0 != ( pFlags & aiProcess_SplitLargeMeshes ) ) ? DeadBeef : max_verts;
  ------------------
  |  Branch (82:21): [True: 0, False: 0]
  ------------------
   83|      0|        return true;
   84|      0|    }
   85|  1.43k|    return false;
   86|  1.43k|}

_ZN6Assimp21OptimizeMeshesProcessD2Ev:
   73|  3.48k|    ~OptimizeMeshesProcess() override = default;

_ZN6Assimp20PretransformVerticesC2Ev:
   90|  3.48k|		mConfigKeepHierarchy(false),
   91|  3.48k|		mConfigNormalize(false),
   92|  3.48k|		mConfigTransform(false),
   93|  3.48k|		mConfigTransformation(),
   94|  3.48k|		mConfigPointCloud(false) {}
_ZNK6Assimp20PretransformVertices8IsActiveEj:
   98|  1.48k|bool PretransformVertices::IsActive(unsigned int pFlags) const {
   99|  1.48k|	return (pFlags & aiProcess_PreTransformVertices) != 0;
  100|  1.48k|}

_ZN6Assimp22ComputePositionEpsilonEPK6aiMesh:
  136|  2.11k|ai_real ComputePositionEpsilon(const aiMesh *pMesh) {
  137|  2.11k|    const ai_real epsilon = ai_real(1e-4);
  138|       |
  139|       |    // calculate the position bounds so we have a reliable epsilon to check position differences against
  140|  2.11k|    aiVector3D minVec, maxVec;
  141|  2.11k|    ArrayBounds(pMesh->mVertices, pMesh->mNumVertices, minVec, maxVec);
  142|  2.11k|    return (maxVec - minVec).Length() * epsilon;
  143|  2.11k|}
_ZN6Assimp28ComputeVertexBoneWeightTableEPK6aiMesh:
  199|    898|VertexWeightTable *ComputeVertexBoneWeightTable(const aiMesh *pMesh) {
  200|    898|    if (!pMesh || !pMesh->mNumVertices || !pMesh->mNumBones) {
  ------------------
  |  Branch (200:9): [True: 0, False: 898]
  |  Branch (200:19): [True: 0, False: 898]
  |  Branch (200:43): [True: 785, False: 113]
  ------------------
  201|    785|        return nullptr;
  202|    785|    }
  203|       |
  204|    113|    VertexWeightTable *avPerVertexWeights = new VertexWeightTable[pMesh->mNumVertices];
  205|  1.22k|    for (unsigned int i = 0; i < pMesh->mNumBones; ++i) {
  ------------------
  |  Branch (205:30): [True: 1.11k, False: 113]
  ------------------
  206|       |
  207|  1.11k|        aiBone *bone = pMesh->mBones[i];
  208|  3.46k|        for (unsigned int a = 0; a < bone->mNumWeights; ++a) {
  ------------------
  |  Branch (208:34): [True: 2.35k, False: 1.11k]
  ------------------
  209|  2.35k|            const aiVertexWeight &weight = bone->mWeights[a];
  210|  2.35k|            avPerVertexWeights[weight.mVertexId].emplace_back(i, weight.mWeight);
  211|  2.35k|        }
  212|  1.11k|    }
  213|    113|    return avPerVertexWeights;
  214|    898|}

_ZNK6Assimp25ComputeSpatialSortProcess8IsActiveEj:
  337|  1.43k|    bool IsActive(unsigned int pFlags) const {
  338|  1.43k|        return nullptr != shared && 0 != (pFlags & (aiProcess_CalcTangentSpace |
  ------------------
  |  Branch (338:16): [True: 1.43k, False: 0]
  |  Branch (338:37): [True: 1.43k, False: 0]
  ------------------
  339|  1.43k|                                                           aiProcess_GenNormals | aiProcess_JoinIdenticalVertices));
  340|  1.43k|    }
_ZN6Assimp25ComputeSpatialSortProcess7ExecuteEP7aiScene:
  342|  1.43k|    void Execute(aiScene *pScene) {
  343|  1.43k|        typedef std::pair<SpatialSort, ai_real> _Type;
  344|  1.43k|        ASSIMP_LOG_DEBUG("Generate spatially-sorted vertex cache");
  345|       |
  346|  1.43k|        std::vector<_Type> *p = new std::vector<_Type>(pScene->mNumMeshes);
  347|  1.43k|        std::vector<_Type>::iterator it = p->begin();
  348|       |
  349|  3.54k|        for (unsigned int i = 0; i < pScene->mNumMeshes; ++i, ++it) {
  ------------------
  |  Branch (349:34): [True: 2.11k, False: 1.43k]
  ------------------
  350|  2.11k|            aiMesh *mesh = pScene->mMeshes[i];
  351|  2.11k|            _Type &blubb = *it;
  352|  2.11k|            blubb.first.Fill(mesh->mVertices, mesh->mNumVertices, sizeof(aiVector3D));
  353|  2.11k|            blubb.second = ComputePositionEpsilon(mesh);
  354|  2.11k|        }
  355|       |
  356|  1.43k|        shared->AddProperty(AI_SPP_SPATIAL_SORT, p);
  ------------------
  |  |  166|  1.43k|#define AI_SPP_SPATIAL_SORT "$Spat"
  ------------------
  357|  1.43k|    }
_ZNK6Assimp25DestroySpatialSortProcess8IsActiveEj:
  363|  1.43k|    bool IsActive(unsigned int pFlags) const {
  364|  1.43k|        return nullptr != shared && 0 != (pFlags & (aiProcess_CalcTangentSpace |
  ------------------
  |  Branch (364:16): [True: 1.43k, False: 0]
  |  Branch (364:37): [True: 1.43k, False: 0]
  ------------------
  365|  1.43k|                                                        aiProcess_GenNormals | aiProcess_JoinIdenticalVertices));
  366|  1.43k|    }
_ZN6Assimp25DestroySpatialSortProcess7ExecuteEP7aiScene:
  368|  1.43k|    void Execute(aiScene * /*pScene*/) {
  369|  1.43k|        shared->RemoveProperty(AI_SPP_SPATIAL_SORT);
  ------------------
  |  |  166|  1.43k|#define AI_SPP_SPATIAL_SORT "$Spat"
  ------------------
  370|  1.43k|    }
_ZN6Assimp18GetColorDifferenceERK9aiColor4tIfES3_:
  250|   400k|inline ai_real GetColorDifference(const aiColor4D &pColor1, const aiColor4D &pColor2) {
  251|   400k|    const aiColor4D c(pColor1.r - pColor2.r, pColor1.g - pColor2.g, pColor1.b - pColor2.b, pColor1.a - pColor2.a);
  252|   400k|    return c.r * c.r + c.g * c.g + c.b * c.b + c.a * c.a;
  253|   400k|}
_ZSt3minIfE10aiVector3tIT_ERKS2_S4_:
   67|  72.8k|inline ::aiVector3t<TReal> min(const ::aiVector3t<TReal> &a, const ::aiVector3t<TReal> &b) {
   68|  72.8k|    return ::aiVector3t<TReal>(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z));
   69|  72.8k|}
_ZSt3maxIfE10aiVector3tIT_ERKS2_S4_:
   73|  72.8k|inline ::aiVector3t<TReal> max(const ::aiVector3t<TReal> &a, const ::aiVector3t<TReal> &b) {
   74|  72.8k|    return ::aiVector3t<TReal>(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z));
   75|  72.8k|}
_ZN6Assimp13MinMaxChooserI10aiVector3tIfEEclERS2_S4_:
  177|  2.11k|    void operator()(aiVector3t<T> &min, aiVector3t<T> &max) {
  178|  2.11k|        max = aiVector3t<T>(-1e10f, -1e10f, -1e10f);
  179|  2.11k|        min = aiVector3t<T>(1e10f, 1e10f, 1e10f);
  180|  2.11k|    }
_ZN6Assimp11ArrayBoundsI10aiVector3tIfEEEvPKT_jRS3_S6_:
  236|  2.11k|inline void ArrayBounds(const T *in, unsigned int size, T &min, T &max) {
  237|  2.11k|    MinMaxChooser<T>()(min, max);
  238|  74.9k|    for (unsigned int i = 0; i < size; ++i) {
  ------------------
  |  Branch (238:30): [True: 72.8k, False: 2.11k]
  ------------------
  239|  72.8k|        min = std::min(in[i], min);
  240|  72.8k|        max = std::max(in[i], max);
  241|  72.8k|    }
  242|  2.11k|}

_ZN6Assimp26RemoveRedundantMatsProcessC2Ev:
   57|  3.48k|RemoveRedundantMatsProcess::RemoveRedundantMatsProcess() : mConfigFixedMaterials() {}
_ZNK6Assimp26RemoveRedundantMatsProcess8IsActiveEj:
   61|  1.48k|bool RemoveRedundantMatsProcess::IsActive( unsigned int pFlags) const {
   62|  1.48k|    return (pFlags & aiProcess_RemoveRedundantMaterials) != 0;
   63|  1.48k|}
_ZN6Assimp26RemoveRedundantMatsProcess15SetupPropertiesEPKNS_8ImporterE:
   67|  1.48k|void RemoveRedundantMatsProcess::SetupProperties(const Importer* pImp) {
   68|       |    // Get value of AI_CONFIG_PP_RRM_EXCLUDE_LIST
   69|       |    mConfigFixedMaterials = pImp->GetPropertyString(AI_CONFIG_PP_RRM_EXCLUDE_LIST,"");
   70|  1.48k|}
_ZN6Assimp26RemoveRedundantMatsProcess7ExecuteEP7aiScene:
   74|  1.48k|void RemoveRedundantMatsProcess::Execute( aiScene* pScene) {
   75|  1.48k|    ASSIMP_LOG_DEBUG("RemoveRedundantMatsProcess begin");
   76|       |
   77|  1.48k|    unsigned int redundantRemoved = 0, unreferencedRemoved = 0;
   78|  1.48k|    if (pScene->mNumMaterials == 0) {
  ------------------
  |  Branch (78:9): [True: 0, False: 1.48k]
  ------------------
   79|      0|        return;
   80|      0|    }
   81|       |
   82|       |    // Find out which materials are referenced by meshes
   83|  1.48k|    std::vector<bool> abReferenced(pScene->mNumMaterials,false);
   84|  2.81k|    for (unsigned int i = 0;i < pScene->mNumMeshes;++i) {
  ------------------
  |  Branch (84:29): [True: 1.32k, False: 1.48k]
  ------------------
   85|  1.32k|        abReferenced[pScene->mMeshes[i]->mMaterialIndex] = true;
   86|  1.32k|    }
   87|       |
   88|       |    // If a list of materials to be excluded was given, match the list with
   89|       |    // our imported materials and 'salt' all positive matches to ensure that
   90|       |    // we get unique hashes later.
   91|  1.48k|    if (mConfigFixedMaterials.length()) {
  ------------------
  |  Branch (91:9): [True: 0, False: 1.48k]
  ------------------
   92|      0|        std::list<std::string> strings;
   93|      0|        ConvertListToStrings(mConfigFixedMaterials,strings);
   94|       |
   95|      0|        for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
  ------------------
  |  Branch (95:34): [True: 0, False: 0]
  ------------------
   96|      0|            aiMaterial* mat = pScene->mMaterials[i];
   97|      0|            ai_assert(mat != nullptr);
   98|      0|            aiString name;
   99|      0|            mat->Get(AI_MATKEY_NAME,name);
  100|       |
  101|      0|            if (name.length != 0) {
  ------------------
  |  Branch (101:17): [True: 0, False: 0]
  ------------------
  102|      0|                std::list<std::string>::const_iterator it = std::find(strings.begin(), strings.end(), name.data);
  103|      0|                if (it != strings.end()) {
  ------------------
  |  Branch (103:21): [True: 0, False: 0]
  ------------------
  104|       |                    // Our brilliant 'salt': A single material property with ~ as first
  105|       |                    // character to mark it as internal and temporary.
  106|      0|                    const int dummy = 1;
  107|      0|                    ((aiMaterial*)mat)->AddProperty(&dummy,1,"~RRM.UniqueMaterial",0,0);
  108|       |
  109|       |                    // Keep this material even if no mesh references it
  110|      0|                    abReferenced[i] = true;
  111|      0|                    ASSIMP_LOG_VERBOSE_DEBUG( "Found positive match in exclusion list: \'", name.data, "\'");
  112|      0|                }
  113|      0|            }
  114|      0|        }
  115|      0|    }
  116|       |
  117|       |    // TODO: re-implement this algorithm to work in-place
  118|  1.48k|    unsigned int *aiMappingTable = new unsigned int[pScene->mNumMaterials];
  119|  4.03k|    for ( unsigned int i=0; i<pScene->mNumMaterials; i++ ) {
  ------------------
  |  Branch (119:29): [True: 2.55k, False: 1.48k]
  ------------------
  120|  2.55k|        aiMappingTable[ i ] = 0;
  121|  2.55k|    }
  122|  1.48k|    unsigned int iNewNum = 0;
  123|       |
  124|       |    // Iterate through all materials and calculate a hash for them
  125|       |    // store all hashes in a list and so a quick search whether
  126|       |    // we do already have a specific hash. This allows us to
  127|       |    // determine which materials are identical.
  128|  1.48k|    uint32_t *aiHashes = new uint32_t[ pScene->mNumMaterials ];
  129|  4.03k|    for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
  ------------------
  |  Branch (129:30): [True: 2.55k, False: 1.48k]
  ------------------
  130|       |        // No mesh is referencing this material, remove it.
  131|  2.55k|        if (!abReferenced[i]) {
  ------------------
  |  Branch (131:13): [True: 1.22k, False: 1.32k]
  ------------------
  132|  1.22k|            ++unreferencedRemoved;
  133|  1.22k|            delete pScene->mMaterials[i];
  134|  1.22k|            pScene->mMaterials[i] = nullptr;
  135|  1.22k|            continue;
  136|  1.22k|        }
  137|       |
  138|       |        // Check all previously mapped materials for a matching hash.
  139|       |        // On a match we can delete this material and just make it ref to the same index.
  140|  1.32k|        uint32_t me = aiHashes[i] = ComputeMaterialHash(pScene->mMaterials[i]);
  141|  1.32k|        for (unsigned int a = 0; a < i;++a) {
  ------------------
  |  Branch (141:34): [True: 0, False: 1.32k]
  ------------------
  142|      0|            if (abReferenced[a] && me == aiHashes[a]) {
  ------------------
  |  Branch (142:17): [True: 0, False: 0]
  |  Branch (142:17): [True: 0, False: 0]
  |  Branch (142:36): [True: 0, False: 0]
  ------------------
  143|      0|                ++redundantRemoved;
  144|      0|                me = 0;
  145|      0|                aiMappingTable[i] = aiMappingTable[a];
  146|      0|                delete pScene->mMaterials[i];
  147|      0|                pScene->mMaterials[i] = nullptr;
  148|      0|                break;
  149|      0|            }
  150|      0|        }
  151|       |        // This is a new material that is referenced, add to the map.
  152|  1.32k|        if (me) {
  ------------------
  |  Branch (152:13): [True: 1.32k, False: 0]
  ------------------
  153|  1.32k|            aiMappingTable[i] = iNewNum++;
  154|  1.32k|        }
  155|  1.32k|    }
  156|       |    // If the new material count differs from the original,
  157|       |    // we need to rebuild the material list and remap mesh material indexes.
  158|  1.48k|    if (iNewNum < 1) {
  ------------------
  |  Branch (158:9): [True: 159, False: 1.32k]
  ------------------
  159|    159|        delete [] aiMappingTable;
  160|    159|        delete [] aiHashes;
  161|    159|        pScene->mNumMaterials = 0;
  162|    159|        return;
  163|    159|    }
  164|  1.32k|    if (iNewNum != pScene->mNumMaterials) {
  ------------------
  |  Branch (164:9): [True: 1.06k, False: 260]
  ------------------
  165|  1.06k|        ai_assert(iNewNum > 0);
  166|  1.06k|        aiMaterial** ppcMaterials = new aiMaterial*[iNewNum];
  167|  1.06k|        ::memset(ppcMaterials,0,sizeof(void*)*iNewNum);
  168|  3.19k|        for (unsigned int p = 0; p < pScene->mNumMaterials;++p) {
  ------------------
  |  Branch (168:34): [True: 2.13k, False: 1.06k]
  ------------------
  169|       |            // if the material is not referenced ... remove it
  170|  2.13k|            if (!abReferenced[p]) {
  ------------------
  |  Branch (170:17): [True: 1.06k, False: 1.06k]
  ------------------
  171|  1.06k|                continue;
  172|  1.06k|            }
  173|       |
  174|       |            // generate new names for modified materials that had no names
  175|  1.06k|            const unsigned int idx = aiMappingTable[p];
  176|  1.06k|            if (ppcMaterials[idx]) {
  ------------------
  |  Branch (176:17): [True: 0, False: 1.06k]
  ------------------
  177|      0|                aiString sz;
  178|      0|                if( ppcMaterials[idx]->Get(AI_MATKEY_NAME, sz) != AI_SUCCESS ) {
  ------------------
  |  Branch (178:21): [True: 0, False: 0]
  ------------------
  179|      0|                    sz.length = ::ai_snprintf(sz.data, AI_MAXLEN,"JoinedMaterial_#%u",p);
  180|      0|                    ((aiMaterial*)ppcMaterials[idx])->AddProperty(&sz,AI_MATKEY_NAME);
  181|      0|                }
  182|  1.06k|            } else {
  183|  1.06k|                ppcMaterials[idx] = pScene->mMaterials[p];
  184|  1.06k|            }
  185|  1.06k|        }
  186|       |        // update all material indices
  187|  2.13k|        for (unsigned int p = 0; p < pScene->mNumMeshes;++p) {
  ------------------
  |  Branch (187:34): [True: 1.06k, False: 1.06k]
  ------------------
  188|  1.06k|            aiMesh* mesh = pScene->mMeshes[p];
  189|  1.06k|            ai_assert(nullptr != mesh);
  190|  1.06k|            mesh->mMaterialIndex = aiMappingTable[mesh->mMaterialIndex];
  191|  1.06k|        }
  192|       |        // delete the old material list
  193|  1.06k|        delete[] pScene->mMaterials;
  194|  1.06k|        pScene->mMaterials = ppcMaterials;
  195|  1.06k|        pScene->mNumMaterials = iNewNum;
  196|  1.06k|    }
  197|       |    // delete temporary storage
  198|  1.32k|    delete[] aiHashes;
  199|  1.32k|    delete[] aiMappingTable;
  200|       |
  201|  1.32k|    if (redundantRemoved == 0 && unreferencedRemoved == 0) {
  ------------------
  |  Branch (201:9): [True: 1.32k, False: 0]
  |  Branch (201:34): [True: 260, False: 1.06k]
  ------------------
  202|    260|        ASSIMP_LOG_DEBUG("RemoveRedundantMatsProcess finished ");
  203|  1.06k|    } else {
  204|       |        ASSIMP_LOG_INFO("RemoveRedundantMatsProcess finished. Removed ", redundantRemoved, " redundant and ",
  205|  1.06k|            unreferencedRemoved, " unused materials.");
  206|  1.06k|    }
  207|  1.32k|}

_ZN6Assimp26RemoveRedundantMatsProcessD2Ev:
   64|  3.48k|    ~RemoveRedundantMatsProcess() override = default;

_ZN6Assimp15RemoveVCProcessC2Ev:
   55|  3.48k|        configDeleteFlags(), mScene() {}
_ZNK6Assimp15RemoveVCProcess8IsActiveEj:
   59|  1.48k|bool RemoveVCProcess::IsActive(unsigned int pFlags) const {
   60|  1.48k|    return (pFlags & aiProcess_RemoveComponent) != 0;
   61|  1.48k|}

_ZN6Assimp12ScaleProcessC2Ev:
   50|  3.48k|ScaleProcess::ScaleProcess() : BaseProcess(), mScale( AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT ) {
   51|       |    // empty
   52|  3.48k|}
_ZNK6Assimp12ScaleProcess8IsActiveEj:
   65|  1.48k|bool ScaleProcess::IsActive( unsigned int pFlags ) const {
   66|  1.48k|    return ( pFlags & aiProcess_GlobalScale ) != 0;
   67|  1.48k|}

_ZN6Assimp18SortByPTypeProcessC2Ev:
   55|  3.48k|SortByPTypeProcess::SortByPTypeProcess() : mConfigRemoveMeshes(0) {}
_ZNK6Assimp18SortByPTypeProcess8IsActiveEj:
   59|  1.48k|bool SortByPTypeProcess::IsActive(unsigned int pFlags) const {
   60|  1.48k|    return (pFlags & aiProcess_SortByPType) != 0;
   61|  1.48k|}
_ZN6Assimp18SortByPTypeProcess15SetupPropertiesEPKNS_8ImporterE:
   64|  1.48k|void SortByPTypeProcess::SetupProperties(const Importer *pImp) {
   65|       |    mConfigRemoveMeshes = pImp->GetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, 0);
   66|  1.48k|}
_Z11UpdateNodesRKNSt3__16vectorIjNS_9allocatorIjEEEEP6aiNode:
   77|  4.68k|void UpdateNodes(const std::vector<unsigned int> &replaceMeshIndex, aiNode *node) {
   78|  4.68k|    ai_assert(node != nullptr);
   79|       |
   80|  4.68k|    if (node->mNumMeshes) {
  ------------------
  |  Branch (80:9): [True: 971, False: 3.71k]
  ------------------
   81|    971|        unsigned int newSize = 0;
   82|  1.94k|        for (unsigned int m = 0; m < node->mNumMeshes; ++m) {
  ------------------
  |  Branch (82:34): [True: 971, False: 971]
  ------------------
   83|    971|            unsigned int add = node->mMeshes[m] << 2;
   84|  4.85k|            for (unsigned int i = 0; i < 4; ++i) {
  ------------------
  |  Branch (84:38): [True: 3.88k, False: 971]
  ------------------
   85|  3.88k|                if (UINT_MAX != replaceMeshIndex[add + i]) {
  ------------------
  |  Branch (85:21): [True: 2.23k, False: 1.65k]
  ------------------
   86|  2.23k|                    ++newSize;
   87|  2.23k|                }
   88|  3.88k|            }
   89|    971|        }
   90|    971|        if (newSize == 0) {
  ------------------
  |  Branch (90:13): [True: 0, False: 971]
  ------------------
   91|      0|            clearMeshesInNode(node);
   92|      0|            return;
   93|      0|        }
   94|       |
   95|       |        // Try to reuse the old array if possible
   96|    971|        unsigned int *newMeshes = (newSize > node->mNumMeshes ? new unsigned int[newSize] : node->mMeshes);
  ------------------
  |  Branch (96:36): [True: 971, False: 0]
  ------------------
   97|  1.94k|        for (unsigned int m = 0; m < node->mNumMeshes; ++m) {
  ------------------
  |  Branch (97:34): [True: 971, False: 971]
  ------------------
   98|    971|            unsigned int add = node->mMeshes[m] << 2;
   99|  4.85k|            for (unsigned int i = 0; i < 4; ++i) {
  ------------------
  |  Branch (99:38): [True: 3.88k, False: 971]
  ------------------
  100|  3.88k|                if (UINT_MAX != replaceMeshIndex[add + i]) {
  ------------------
  |  Branch (100:21): [True: 2.23k, False: 1.65k]
  ------------------
  101|  2.23k|                    *newMeshes++ = replaceMeshIndex[add + i];
  102|  2.23k|                }
  103|  3.88k|            }
  104|    971|        }
  105|    971|        if (newSize > node->mNumMeshes) {
  ------------------
  |  Branch (105:13): [True: 971, False: 0]
  ------------------
  106|    971|            clearMeshesInNode(node);
  107|    971|        }
  108|    971|        node->mMeshes = newMeshes - (node->mNumMeshes = newSize);
  109|    971|    }
  110|       |
  111|       |    // call all subnodes recursively
  112|  8.46k|    for (unsigned int m = 0; m < node->mNumChildren; ++m) {
  ------------------
  |  Branch (112:30): [True: 3.78k, False: 4.68k]
  ------------------
  113|  3.78k|        UpdateNodes(replaceMeshIndex, node->mChildren[m]);
  114|  3.78k|    }
  115|  4.68k|}
_ZN6Assimp18SortByPTypeProcess7ExecuteEP7aiScene:
  119|  1.48k|void SortByPTypeProcess::Execute(aiScene *pScene) {
  120|  1.48k|    if (0 == pScene->mNumMeshes) {
  ------------------
  |  Branch (120:9): [True: 159, False: 1.32k]
  ------------------
  121|    159|        ASSIMP_LOG_DEBUG("SortByPTypeProcess skipped, there are no meshes");
  122|    159|        return;
  123|    159|    }
  124|       |
  125|  1.48k|    ASSIMP_LOG_DEBUG("SortByPTypeProcess begin");
  126|       |
  127|  1.32k|    unsigned int aiNumMeshesPerPType[4] = { 0, 0, 0, 0 };
  128|       |
  129|  1.32k|    std::vector<aiMesh *> outMeshes;
  130|  1.32k|    outMeshes.reserve(static_cast<size_t>(pScene->mNumMeshes) << 1u);
  131|       |
  132|  1.32k|    bool bAnyChanges = false;
  133|       |
  134|  1.32k|    std::vector<unsigned int> replaceMeshIndex(pScene->mNumMeshes * 4, UINT_MAX);
  135|  1.32k|    std::vector<unsigned int>::iterator meshIdx = replaceMeshIndex.begin();
  136|  2.65k|    for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
  ------------------
  |  Branch (136:30): [True: 1.32k, False: 1.32k]
  ------------------
  137|  1.32k|        aiMesh *const mesh = pScene->mMeshes[i];
  138|  1.32k|        if (mesh->mPrimitiveTypes == 0) {
  ------------------
  |  Branch (138:13): [True: 0, False: 1.32k]
  ------------------
  139|      0|            for (size_t idx = 0; idx < outMeshes.size(); ++idx) {
  ------------------
  |  Branch (139:34): [True: 0, False: 0]
  ------------------
  140|      0|                delete outMeshes[idx];
  141|      0|            }
  142|      0|            throw DeadlyImportError("Mesh with invalid primitive type: ", mesh->mName.C_Str());
  143|      0|        }
  144|       |
  145|       |        // if there's just one primitive type in the mesh there's nothing to do for us
  146|  1.32k|        unsigned int num = 0;
  147|  1.32k|        if (mesh->mPrimitiveTypes & aiPrimitiveType_POINT) {
  ------------------
  |  Branch (147:13): [True: 695, False: 631]
  ------------------
  148|    695|            ++aiNumMeshesPerPType[0];
  149|    695|            ++num;
  150|    695|        }
  151|  1.32k|        if (mesh->mPrimitiveTypes & aiPrimitiveType_LINE) {
  ------------------
  |  Branch (151:13): [True: 957, False: 369]
  ------------------
  152|    957|            ++aiNumMeshesPerPType[1];
  153|    957|            ++num;
  154|    957|        }
  155|  1.32k|        if (mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE) {
  ------------------
  |  Branch (155:13): [True: 836, False: 490]
  ------------------
  156|    836|            ++aiNumMeshesPerPType[2];
  157|    836|            ++num;
  158|    836|        }
  159|  1.32k|        if (mesh->mPrimitiveTypes & aiPrimitiveType_POLYGON) {
  ------------------
  |  Branch (159:13): [True: 0, False: 1.32k]
  ------------------
  160|      0|            ++aiNumMeshesPerPType[3];
  161|      0|            ++num;
  162|      0|        }
  163|       |
  164|  1.32k|        if (1 == num) {
  ------------------
  |  Branch (164:13): [True: 428, False: 898]
  ------------------
  165|    428|            if (!(mConfigRemoveMeshes & mesh->mPrimitiveTypes)) {
  ------------------
  |  Branch (165:17): [True: 428, False: 0]
  ------------------
  166|    428|                *meshIdx = static_cast<unsigned int>(outMeshes.size());
  167|    428|                outMeshes.emplace_back(mesh);
  168|    428|                pScene->mMeshes[i] = nullptr; // Indicate ownership transfer
  169|    428|            } else {
  170|      0|                delete mesh;
  171|      0|                pScene->mMeshes[i] = nullptr;
  172|      0|                bAnyChanges = true;
  173|      0|            }
  174|       |
  175|    428|            meshIdx += 4;
  176|    428|            continue;
  177|    428|        }
  178|    898|        bAnyChanges = true;
  179|       |
  180|       |        // reuse our current mesh arrays for the submesh
  181|       |        // with the largest number of primitives
  182|    898|        unsigned int aiNumPerPType[4] = { 0, 0, 0, 0 };
  183|    898|        aiFace *pFirstFace = mesh->mFaces;
  184|    898|        if (pFirstFace == nullptr) {
  ------------------
  |  Branch (184:13): [True: 0, False: 898]
  ------------------
  185|      0|            continue;
  186|      0|        }
  187|       |
  188|    898|        aiFace *const pLastFace = pFirstFace + mesh->mNumFaces;
  189|       |
  190|    898|        unsigned int numPolyVerts = 0;
  191|  30.4k|        for (; pFirstFace != pLastFace; ++pFirstFace) {
  ------------------
  |  Branch (191:16): [True: 29.5k, False: 898]
  ------------------
  192|  29.5k|            if (pFirstFace->mNumIndices >= 1 && pFirstFace->mNumIndices <= 3)
  ------------------
  |  Branch (192:17): [True: 29.5k, False: 0]
  |  Branch (192:49): [True: 29.5k, False: 0]
  ------------------
  193|  29.5k|                ++aiNumPerPType[pFirstFace->mNumIndices - 1];
  194|      0|            else {
  195|      0|                ++aiNumPerPType[3];
  196|      0|                numPolyVerts += pFirstFace->mNumIndices;
  197|      0|            }
  198|  29.5k|            if (pFirstFace->mNumIndices == 0) {
  ------------------
  |  Branch (198:17): [True: 0, False: 29.5k]
  ------------------
  199|      0|                ASSIMP_LOG_WARN("Face with 0 indices treated as polygon");
  200|      0|            }
  201|  29.5k|        }
  202|       |
  203|    898|        VertexWeightTable *avw = ComputeVertexBoneWeightTable(mesh);
  204|  4.49k|        for (unsigned int real = 0; real < 4; ++real, ++meshIdx) {
  ------------------
  |  Branch (204:37): [True: 3.59k, False: 898]
  ------------------
  205|  3.59k|            if (!aiNumPerPType[real] || mConfigRemoveMeshes & (1u << real)) {
  ------------------
  |  Branch (205:17): [True: 1.53k, False: 2.06k]
  |  Branch (205:41): [True: 0, False: 2.06k]
  ------------------
  206|  1.53k|                continue;
  207|  1.53k|            }
  208|       |
  209|  2.06k|            *meshIdx = (unsigned int)outMeshes.size();
  210|  2.06k|            outMeshes.push_back(new aiMesh());
  211|  2.06k|            aiMesh *out = outMeshes.back();
  212|       |
  213|       |            // the name carries the adjacency information between the meshes
  214|  2.06k|            out->mName = mesh->mName;
  215|       |
  216|       |            // copy data members
  217|  2.06k|            out->mPrimitiveTypes = 1u << real;
  218|  2.06k|            out->mMaterialIndex = mesh->mMaterialIndex;
  219|       |
  220|       |            // allocate output storage
  221|  2.06k|            out->mNumFaces = aiNumPerPType[real];
  222|  2.06k|            aiFace *outFaces = out->mFaces = new aiFace[out->mNumFaces];
  223|       |
  224|  2.06k|            out->mNumVertices = (3 == real ? numPolyVerts : out->mNumFaces * (real + 1));
  ------------------
  |  Branch (224:34): [True: 0, False: 2.06k]
  ------------------
  225|       |
  226|  2.06k|            aiVector3D *vert(nullptr), *nor(nullptr), *tan(nullptr), *bit(nullptr);
  227|  2.06k|            aiVector3D *uv[AI_MAX_NUMBER_OF_TEXTURECOORDS];
  228|  2.06k|            aiColor4D *cols[AI_MAX_NUMBER_OF_COLOR_SETS];
  229|       |
  230|  2.06k|            if (mesh->mVertices) {
  ------------------
  |  Branch (230:17): [True: 2.06k, False: 0]
  ------------------
  231|  2.06k|                vert = out->mVertices = new aiVector3D[out->mNumVertices];
  232|  2.06k|            }
  233|       |
  234|  2.06k|            if (mesh->mNormals) {
  ------------------
  |  Branch (234:17): [True: 1.12k, False: 934]
  ------------------
  235|  1.12k|                nor = out->mNormals = new aiVector3D[out->mNumVertices];
  236|  1.12k|            }
  237|       |
  238|  2.06k|            if (mesh->mTangents) {
  ------------------
  |  Branch (238:17): [True: 44, False: 2.01k]
  ------------------
  239|     44|                tan = out->mTangents = new aiVector3D[out->mNumVertices];
  240|     44|                bit = out->mBitangents = new aiVector3D[out->mNumVertices];
  241|     44|            }
  242|       |
  243|  18.5k|            for (unsigned int j = 0; j < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++j) {
  ------------------
  |  Branch (243:38): [True: 16.4k, False: 2.06k]
  ------------------
  244|  16.4k|                uv[j] = nullptr;
  245|  16.4k|                if (mesh->mTextureCoords[j]) {
  ------------------
  |  Branch (245:21): [True: 564, False: 15.9k]
  ------------------
  246|    564|                    uv[j] = out->mTextureCoords[j] = new aiVector3D[out->mNumVertices];
  247|    564|                }
  248|       |
  249|  16.4k|                out->mNumUVComponents[j] = mesh->mNumUVComponents[j];
  250|  16.4k|            }
  251|       |
  252|  18.5k|            for (unsigned int j = 0; j < AI_MAX_NUMBER_OF_COLOR_SETS; ++j) {
  ------------------
  |  Branch (252:38): [True: 16.4k, False: 2.06k]
  ------------------
  253|  16.4k|                cols[j] = nullptr;
  254|  16.4k|                if (mesh->mColors[j]) {
  ------------------
  |  Branch (254:21): [True: 260, False: 16.2k]
  ------------------
  255|    260|                    cols[j] = out->mColors[j] = new aiColor4D[out->mNumVertices];
  256|    260|                }
  257|  16.4k|            }
  258|       |
  259|  2.06k|            if (mesh->mNumAnimMeshes > 0 && mesh->mAnimMeshes) {
  ------------------
  |  Branch (259:17): [True: 0, False: 2.06k]
  |  Branch (259:45): [True: 0, False: 0]
  ------------------
  260|      0|                out->mNumAnimMeshes = mesh->mNumAnimMeshes;
  261|      0|                out->mAnimMeshes = new aiAnimMesh *[out->mNumAnimMeshes];
  262|      0|            }
  263|       |
  264|  2.06k|            for (unsigned int j = 0; j < mesh->mNumAnimMeshes; ++j) {
  ------------------
  |  Branch (264:38): [True: 0, False: 2.06k]
  ------------------
  265|      0|                aiAnimMesh *animMesh = mesh->mAnimMeshes[j];
  266|      0|                aiAnimMesh *outAnimMesh = out->mAnimMeshes[j] = new aiAnimMesh;
  267|      0|                outAnimMesh->mNumVertices = out->mNumVertices;
  268|      0|                if (animMesh->mVertices)
  ------------------
  |  Branch (268:21): [True: 0, False: 0]
  ------------------
  269|      0|                    outAnimMesh->mVertices = new aiVector3D[out->mNumVertices];
  270|      0|                else
  271|      0|                    outAnimMesh->mVertices = nullptr;
  272|      0|                if (animMesh->mNormals)
  ------------------
  |  Branch (272:21): [True: 0, False: 0]
  ------------------
  273|      0|                    outAnimMesh->mNormals = new aiVector3D[out->mNumVertices];
  274|      0|                else
  275|      0|                    outAnimMesh->mNormals = nullptr;
  276|      0|                if (animMesh->mTangents)
  ------------------
  |  Branch (276:21): [True: 0, False: 0]
  ------------------
  277|      0|                    outAnimMesh->mTangents = new aiVector3D[out->mNumVertices];
  278|      0|                else
  279|      0|                    outAnimMesh->mTangents = nullptr;
  280|      0|                if (animMesh->mBitangents)
  ------------------
  |  Branch (280:21): [True: 0, False: 0]
  ------------------
  281|      0|                    outAnimMesh->mBitangents = new aiVector3D[out->mNumVertices];
  282|      0|                else
  283|      0|                    outAnimMesh->mBitangents = nullptr;
  284|      0|                for (int jj = 0; jj < AI_MAX_NUMBER_OF_COLOR_SETS; ++jj) {
  ------------------
  |  Branch (284:34): [True: 0, False: 0]
  ------------------
  285|      0|                    if (animMesh->mColors[jj])
  ------------------
  |  Branch (285:25): [True: 0, False: 0]
  ------------------
  286|      0|                        outAnimMesh->mColors[jj] = new aiColor4D[out->mNumVertices];
  287|      0|                    else
  288|      0|                        outAnimMesh->mColors[jj] = nullptr;
  289|      0|                }
  290|      0|                for (int jj = 0; jj < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++jj) {
  ------------------
  |  Branch (290:34): [True: 0, False: 0]
  ------------------
  291|      0|                    if (animMesh->mTextureCoords[jj])
  ------------------
  |  Branch (291:25): [True: 0, False: 0]
  ------------------
  292|      0|                        outAnimMesh->mTextureCoords[jj] = new aiVector3D[out->mNumVertices];
  293|      0|                    else
  294|      0|                        outAnimMesh->mTextureCoords[jj] = nullptr;
  295|      0|                }
  296|      0|            }
  297|       |
  298|  2.06k|            typedef std::vector<aiVertexWeight> TempBoneInfo;
  299|  2.06k|            std::vector<TempBoneInfo> tempBones(mesh->mNumBones);
  300|       |
  301|       |            // try to guess how much storage we'll need
  302|  4.31k|            for (unsigned int q = 0; q < mesh->mNumBones; ++q) {
  ------------------
  |  Branch (302:38): [True: 2.25k, False: 2.06k]
  ------------------
  303|  2.25k|                tempBones[q].reserve(mesh->mBones[q]->mNumWeights / (num - 1));
  304|  2.25k|            }
  305|       |
  306|  2.06k|            unsigned int outIdx = 0;
  307|  2.06k|            unsigned int amIdx = 0; // AnimMesh index
  308|  70.7k|            for (unsigned int m = 0; m < mesh->mNumFaces; ++m) {
  ------------------
  |  Branch (308:38): [True: 68.6k, False: 2.06k]
  ------------------
  309|  68.6k|                aiFace &in = mesh->mFaces[m];
  310|  68.6k|                if ((real == 3 && in.mNumIndices <= 3) || (real != 3 && in.mNumIndices != real + 1)) {
  ------------------
  |  Branch (310:22): [True: 0, False: 68.6k]
  |  Branch (310:35): [True: 0, False: 0]
  |  Branch (310:60): [True: 68.6k, False: 0]
  |  Branch (310:73): [True: 39.1k, False: 29.5k]
  ------------------
  311|  39.1k|                    continue;
  312|  39.1k|                }
  313|       |
  314|  29.5k|                outFaces->mNumIndices = in.mNumIndices;
  315|  29.5k|                outFaces->mIndices = in.mIndices;
  316|       |
  317|   101k|                for (unsigned int q = 0; q < in.mNumIndices; ++q) {
  ------------------
  |  Branch (317:42): [True: 71.9k, False: 29.5k]
  ------------------
  318|  71.9k|                    unsigned int idx = in.mIndices[q];
  319|       |
  320|       |                    // process all bones of this index
  321|  71.9k|                    if (avw) {
  ------------------
  |  Branch (321:25): [True: 846, False: 71.0k]
  ------------------
  322|    846|                        VertexWeightTable &tbl = avw[idx];
  323|    846|                        for (VertexWeightTable::const_iterator it = tbl.begin(), end = tbl.end();
  324|  6.73k|                                it != end; ++it) {
  ------------------
  |  Branch (324:33): [True: 5.89k, False: 846]
  ------------------
  325|  5.89k|                            tempBones[(*it).first].emplace_back(outIdx, (*it).second);
  326|  5.89k|                        }
  327|    846|                    }
  328|       |
  329|  71.9k|                    if (vert) {
  ------------------
  |  Branch (329:25): [True: 71.9k, False: 0]
  ------------------
  330|  71.9k|                        *vert++ = mesh->mVertices[idx];
  331|  71.9k|                    }
  332|  71.9k|                    if (nor)
  ------------------
  |  Branch (332:25): [True: 16.0k, False: 55.8k]
  ------------------
  333|  16.0k|                        *nor++ = mesh->mNormals[idx];
  334|  71.9k|                    if (tan) {
  ------------------
  |  Branch (334:25): [True: 319, False: 71.6k]
  ------------------
  335|    319|                        *tan++ = mesh->mTangents[idx];
  336|    319|                        *bit++ = mesh->mBitangents[idx];
  337|    319|                    }
  338|       |
  339|  79.9k|                    for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++pp) {
  ------------------
  |  Branch (339:47): [True: 79.9k, False: 0]
  ------------------
  340|  79.9k|                        if (!uv[pp])
  ------------------
  |  Branch (340:29): [True: 71.9k, False: 8.06k]
  ------------------
  341|  71.9k|                            break;
  342|  8.06k|                        *uv[pp]++ = mesh->mTextureCoords[pp][idx];
  343|  8.06k|                    }
  344|       |
  345|  73.1k|                    for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_COLOR_SETS; ++pp) {
  ------------------
  |  Branch (345:47): [True: 73.1k, False: 0]
  ------------------
  346|  73.1k|                        if (!cols[pp])
  ------------------
  |  Branch (346:29): [True: 71.9k, False: 1.24k]
  ------------------
  347|  71.9k|                            break;
  348|  1.24k|                        *cols[pp]++ = mesh->mColors[pp][idx];
  349|  1.24k|                    }
  350|       |
  351|  71.9k|                    unsigned int pp = 0;
  352|  71.9k|                    for (; pp < mesh->mNumAnimMeshes; ++pp) {
  ------------------
  |  Branch (352:28): [True: 0, False: 71.9k]
  ------------------
  353|      0|                        aiAnimMesh *animMesh = mesh->mAnimMeshes[pp];
  354|      0|                        aiAnimMesh *outAnimMesh = out->mAnimMeshes[pp];
  355|      0|                        if (animMesh->mVertices)
  ------------------
  |  Branch (355:29): [True: 0, False: 0]
  ------------------
  356|      0|                            outAnimMesh->mVertices[amIdx] = animMesh->mVertices[idx];
  357|      0|                        if (animMesh->mNormals)
  ------------------
  |  Branch (357:29): [True: 0, False: 0]
  ------------------
  358|      0|                            outAnimMesh->mNormals[amIdx] = animMesh->mNormals[idx];
  359|      0|                        if (animMesh->mTangents)
  ------------------
  |  Branch (359:29): [True: 0, False: 0]
  ------------------
  360|      0|                            outAnimMesh->mTangents[amIdx] = animMesh->mTangents[idx];
  361|      0|                        if (animMesh->mBitangents)
  ------------------
  |  Branch (361:29): [True: 0, False: 0]
  ------------------
  362|      0|                            outAnimMesh->mBitangents[amIdx] = animMesh->mBitangents[idx];
  363|      0|                        for (int jj = 0; jj < AI_MAX_NUMBER_OF_COLOR_SETS; ++jj) {
  ------------------
  |  Branch (363:42): [True: 0, False: 0]
  ------------------
  364|      0|                            if (animMesh->mColors[jj])
  ------------------
  |  Branch (364:33): [True: 0, False: 0]
  ------------------
  365|      0|                                outAnimMesh->mColors[jj][amIdx] = animMesh->mColors[jj][idx];
  366|      0|                        }
  367|      0|                        for (int jj = 0; jj < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++jj) {
  ------------------
  |  Branch (367:42): [True: 0, False: 0]
  ------------------
  368|      0|                            if (animMesh->mTextureCoords[jj])
  ------------------
  |  Branch (368:33): [True: 0, False: 0]
  ------------------
  369|      0|                                outAnimMesh->mTextureCoords[jj][amIdx] = animMesh->mTextureCoords[jj][idx];
  370|      0|                        }
  371|      0|                    }
  372|  71.9k|                    if (pp == mesh->mNumAnimMeshes)
  ------------------
  |  Branch (372:25): [True: 71.9k, False: 0]
  ------------------
  373|  71.9k|                        ++amIdx;
  374|       |
  375|  71.9k|                    in.mIndices[q] = outIdx++;
  376|  71.9k|                }
  377|       |
  378|  29.5k|                in.mIndices = nullptr;
  379|  29.5k|                ++outFaces;
  380|  29.5k|            }
  381|  2.06k|            ai_assert(outFaces == out->mFaces + out->mNumFaces);
  382|       |
  383|       |            // now generate output bones
  384|  4.31k|            for (unsigned int q = 0; q < mesh->mNumBones; ++q) {
  ------------------
  |  Branch (384:38): [True: 2.25k, False: 2.06k]
  ------------------
  385|  2.25k|                if (!tempBones[q].empty()) {
  ------------------
  |  Branch (385:21): [True: 1.84k, False: 414]
  ------------------
  386|  1.84k|                    ++out->mNumBones;
  387|  1.84k|                }
  388|  2.25k|            }
  389|       |
  390|  2.06k|            if (out->mNumBones) {
  ------------------
  |  Branch (390:17): [True: 223, False: 1.83k]
  ------------------
  391|    223|                out->mBones = new aiBone *[out->mNumBones];
  392|  2.42k|                for (unsigned int q = 0, boneIdx = 0; q < mesh->mNumBones; ++q) {
  ------------------
  |  Branch (392:55): [True: 2.19k, False: 223]
  ------------------
  393|  2.19k|                    TempBoneInfo &in = tempBones[q];
  394|  2.19k|                    if (in.empty()) {
  ------------------
  |  Branch (394:25): [True: 354, False: 1.84k]
  ------------------
  395|    354|                        continue;
  396|    354|                    }
  397|       |
  398|  1.84k|                    aiBone *srcBone = mesh->mBones[q];
  399|  1.84k|                    aiBone *bone = out->mBones[boneIdx] = new aiBone();
  400|       |
  401|  1.84k|                    bone->mName = srcBone->mName;
  402|  1.84k|                    bone->mOffsetMatrix = srcBone->mOffsetMatrix;
  403|       |
  404|  1.84k|                    bone->mNumWeights = (unsigned int)in.size();
  405|  1.84k|                    bone->mWeights = new aiVertexWeight[bone->mNumWeights];
  406|       |
  407|  1.84k|                    ::memcpy(bone->mWeights, &in[0], bone->mNumWeights * sizeof(aiVertexWeight));
  408|       |
  409|  1.84k|                    ++boneIdx;
  410|  1.84k|                }
  411|    223|            }
  412|  2.06k|        }
  413|       |
  414|       |        // delete the per-vertex bone weights table
  415|    898|        delete[] avw;
  416|       |
  417|       |        // delete the input mesh
  418|    898|        delete mesh;
  419|       |
  420|       |        // avoid invalid pointer
  421|    898|        pScene->mMeshes[i] = nullptr;
  422|    898|    }
  423|       |
  424|  1.32k|    if (outMeshes.empty()) {
  ------------------
  |  Branch (424:9): [True: 0, False: 1.32k]
  ------------------
  425|       |        // This should not occur
  426|      0|        throw DeadlyImportError("No meshes remaining");
  427|      0|    }
  428|       |
  429|       |    // If we added at least one mesh process all nodes in the node
  430|       |    // graph and update their respective mesh indices.
  431|  1.32k|    if (bAnyChanges) {
  ------------------
  |  Branch (431:9): [True: 898, False: 428]
  ------------------
  432|    898|        UpdateNodes(replaceMeshIndex, pScene->mRootNode);
  433|    898|    }
  434|       |
  435|  1.32k|    if (outMeshes.size() != pScene->mNumMeshes) {
  ------------------
  |  Branch (435:9): [True: 898, False: 428]
  ------------------
  436|    898|        delete[] pScene->mMeshes;
  437|    898|        pScene->mNumMeshes = (unsigned int)outMeshes.size();
  438|    898|        pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
  439|    898|    }
  440|  1.32k|    ::memcpy(pScene->mMeshes, &outMeshes[0], pScene->mNumMeshes * sizeof(void *));
  441|       |
  442|  1.32k|    if (!DefaultLogger::isNullLogger()) {
  ------------------
  |  Branch (442:9): [True: 0, False: 1.32k]
  ------------------
  443|      0|        char buffer[1024];
  444|      0|        ::ai_snprintf(buffer, 1024, "Points: %u%s, Lines: %u%s, Triangles: %u%s, Polygons: %u%s (Meshes, X = removed)",
  445|      0|                aiNumMeshesPerPType[0], ((mConfigRemoveMeshes & aiPrimitiveType_POINT) ? "X" : ""),
  ------------------
  |  Branch (445:42): [True: 0, False: 0]
  ------------------
  446|      0|                aiNumMeshesPerPType[1], ((mConfigRemoveMeshes & aiPrimitiveType_LINE) ? "X" : ""),
  ------------------
  |  Branch (446:42): [True: 0, False: 0]
  ------------------
  447|      0|                aiNumMeshesPerPType[2], ((mConfigRemoveMeshes & aiPrimitiveType_TRIANGLE) ? "X" : ""),
  ------------------
  |  Branch (447:42): [True: 0, False: 0]
  ------------------
  448|      0|                aiNumMeshesPerPType[3], ((mConfigRemoveMeshes & aiPrimitiveType_POLYGON) ? "X" : ""));
  ------------------
  |  Branch (448:42): [True: 0, False: 0]
  ------------------
  449|      0|        ASSIMP_LOG_INFO(buffer);
  450|       |        ASSIMP_LOG_DEBUG("SortByPTypeProcess finished");
  451|      0|    }
  452|  1.32k|}
SortByPTypeProcess.cpp:_ZL17clearMeshesInNodeP6aiNode:
   69|    971|static void clearMeshesInNode(aiNode *node) {
   70|    971|    delete[] node->mMeshes;
   71|    971|    node->mNumMeshes = 0;
   72|    971|    node->mMeshes = nullptr;
   73|    971|}

_ZN6Assimp23SplitByBoneCountProcessC2Ev:
   60|  3.48k|SplitByBoneCountProcess::SplitByBoneCountProcess() : mMaxBoneCount(AI_SBBC_DEFAULT_MAX_BONES) {}
_ZNK6Assimp23SplitByBoneCountProcess8IsActiveEj:
   64|  1.43k|bool SplitByBoneCountProcess::IsActive( unsigned int pFlags) const {
   65|  1.43k|    return !!(pFlags & aiProcess_SplitByBoneCount);
   66|  1.43k|}

_ZN6Assimp23SplitByBoneCountProcessD2Ev:
   66|  3.48k|    ~SplitByBoneCountProcess() override = default;

_ZN6Assimp32SplitLargeMeshesProcess_TriangleC2Ev:
   51|  3.48k|SplitLargeMeshesProcess_Triangle::SplitLargeMeshesProcess_Triangle() {
   52|       |    LIMIT = AI_SLM_DEFAULT_MAX_TRIANGLES;
   53|  3.48k|}
_ZNK6Assimp32SplitLargeMeshesProcess_Triangle8IsActiveEj:
   57|  1.43k|bool SplitLargeMeshesProcess_Triangle::IsActive( unsigned int pFlags) const {
   58|  1.43k|    return (pFlags & aiProcess_SplitLargeMeshes) != 0;
   59|  1.43k|}
_ZN6Assimp32SplitLargeMeshesProcess_Triangle7ExecuteEP7aiScene:
   63|  1.43k|void SplitLargeMeshesProcess_Triangle::Execute( aiScene* pScene) {
   64|  1.43k|    if (0xffffffff == this->LIMIT || nullptr == pScene ) {
  ------------------
  |  Branch (64:9): [True: 0, False: 1.43k]
  |  Branch (64:38): [True: 0, False: 1.43k]
  ------------------
   65|      0|        return;
   66|      0|    }
   67|       |
   68|  1.43k|    ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Triangle begin");
   69|  1.43k|    std::vector<std::pair<aiMesh*, unsigned int> > avList;
   70|       |
   71|  3.54k|    for( unsigned int a = 0; a < pScene->mNumMeshes; ++a) {
  ------------------
  |  Branch (71:30): [True: 2.11k, False: 1.43k]
  ------------------
   72|  2.11k|        this->SplitMesh(a, pScene->mMeshes[a],avList);
   73|  2.11k|    }
   74|       |
   75|  1.43k|    if (avList.size() == pScene->mNumMeshes) {
  ------------------
  |  Branch (75:9): [True: 1.43k, False: 0]
  ------------------
   76|  1.43k|        ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Triangle finished. There was nothing to do");
   77|  1.43k|    }
   78|       |
   79|       |    // it seems something has been split. rebuild the mesh list
   80|  1.43k|    delete[] pScene->mMeshes;
   81|  1.43k|    pScene->mNumMeshes = (unsigned int)avList.size();
   82|  1.43k|    pScene->mMeshes = new aiMesh*[avList.size()];
   83|       |
   84|  3.54k|    for (unsigned int i = 0; i < avList.size();++i) {
  ------------------
  |  Branch (84:30): [True: 2.11k, False: 1.43k]
  ------------------
   85|  2.11k|        pScene->mMeshes[i] = avList[i].first;
   86|  2.11k|    }
   87|       |
   88|       |    // now we need to update all nodes
   89|  1.43k|    this->UpdateNode(pScene->mRootNode,avList);
   90|       |    ASSIMP_LOG_INFO("SplitLargeMeshesProcess_Triangle finished. Meshes have been split");
   91|  1.43k|}
_ZN6Assimp32SplitLargeMeshesProcess_Triangle15SetupPropertiesEPKNS_8ImporterE:
   95|  1.43k|void SplitLargeMeshesProcess_Triangle::SetupProperties( const Importer* pImp) {
   96|       |    // get the current value of the split property
   97|  1.43k|    this->LIMIT = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT,AI_SLM_DEFAULT_MAX_TRIANGLES);
   98|  1.43k|}
_ZN6Assimp32SplitLargeMeshesProcess_Triangle10UpdateNodeEP6aiNodeRKNSt3__16vectorINS3_4pairIP6aiMeshjEENS3_9allocatorIS8_EEEE:
  102|  6.85k|void SplitLargeMeshesProcess_Triangle::UpdateNode(aiNode* pcNode, const std::vector<std::pair<aiMesh*, unsigned int> >& avList) {
  103|  6.85k|    if (pcNode == nullptr) {
  ------------------
  |  Branch (103:9): [True: 0, False: 6.85k]
  ------------------
  104|      0|        ASSIMP_LOG_WARN("UpdateNode skipped, nullptr detected.");
  105|      0|        return;
  106|      0|    }
  107|       |
  108|       |    // for every index in out list build a new entry
  109|  6.85k|    std::vector<unsigned int> aiEntries;
  110|  6.85k|    aiEntries.reserve(pcNode->mNumMeshes + 1);
  111|  9.12k|    for (unsigned int i = 0; i < pcNode->mNumMeshes;++i) {
  ------------------
  |  Branch (111:30): [True: 2.27k, False: 6.85k]
  ------------------
  112|  6.61k|        for (unsigned int a = 0; a < avList.size();++a) {
  ------------------
  |  Branch (112:34): [True: 4.34k, False: 2.27k]
  ------------------
  113|  4.34k|            if (avList[a].second == pcNode->mMeshes[i]) {
  ------------------
  |  Branch (113:17): [True: 2.27k, False: 2.07k]
  ------------------
  114|  2.27k|                aiEntries.push_back(a);
  115|  2.27k|            }
  116|  4.34k|        }
  117|  2.27k|    }
  118|       |
  119|       |    // now build the new list
  120|  6.85k|    delete[] pcNode->mMeshes;
  121|  6.85k|    pcNode->mNumMeshes = (unsigned int)aiEntries.size();
  122|  6.85k|    pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
  123|       |
  124|  9.12k|    for (unsigned int b = 0; b < pcNode->mNumMeshes;++b) {
  ------------------
  |  Branch (124:30): [True: 2.27k, False: 6.85k]
  ------------------
  125|  2.27k|        pcNode->mMeshes[b] = aiEntries[b];
  126|  2.27k|    }
  127|       |
  128|       |    // recursively update all other nodes
  129|  12.2k|    for (unsigned int i = 0; i < pcNode->mNumChildren;++i) {
  ------------------
  |  Branch (129:30): [True: 5.42k, False: 6.85k]
  ------------------
  130|  5.42k|        UpdateNode ( pcNode->mChildren[i], avList );
  131|  5.42k|    }
  132|  6.85k|}
_ZN6Assimp32SplitLargeMeshesProcess_Triangle9SplitMeshEjP6aiMeshRNSt3__16vectorINS3_4pairIS2_jEENS3_9allocatorIS6_EEEE:
  139|  2.11k|        std::vector<std::pair<aiMesh*, unsigned int> >& avList) {
  140|  2.11k|    if (pMesh->mNumFaces > SplitLargeMeshesProcess_Triangle::LIMIT) {
  ------------------
  |  Branch (140:9): [True: 0, False: 2.11k]
  ------------------
  141|      0|        ASSIMP_LOG_INFO("Mesh exceeds the triangle limit. It will be split ...");
  142|       |
  143|       |        // we need to split this mesh into sub meshes
  144|       |        // determine the size of a submesh
  145|      0|        const unsigned int iSubMeshes = (pMesh->mNumFaces / LIMIT) + 1;
  146|       |
  147|      0|        const unsigned int iOutFaceNum = pMesh->mNumFaces / iSubMeshes;
  148|      0|        const unsigned int iOutVertexNum = iOutFaceNum * 3;
  149|       |
  150|       |        // now generate all submeshes
  151|      0|        for (unsigned int i = 0; i < iSubMeshes;++i) {
  ------------------
  |  Branch (151:34): [True: 0, False: 0]
  ------------------
  152|      0|            aiMesh* pcMesh          = new aiMesh;
  153|      0|            pcMesh->mNumFaces       = iOutFaceNum;
  154|      0|            pcMesh->mMaterialIndex  = pMesh->mMaterialIndex;
  155|       |
  156|       |            // the name carries the adjacency information between the meshes
  157|      0|            pcMesh->mName = pMesh->mName;
  158|       |
  159|      0|            if (i == iSubMeshes-1) {
  ------------------
  |  Branch (159:17): [True: 0, False: 0]
  ------------------
  160|      0|                pcMesh->mNumFaces = iOutFaceNum + (
  161|      0|                    pMesh->mNumFaces - iOutFaceNum * iSubMeshes);
  162|      0|            }
  163|       |            // copy the list of faces
  164|      0|            pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
  165|       |
  166|      0|            const unsigned int iBase = iOutFaceNum * i;
  167|       |
  168|       |            // get the total number of indices
  169|      0|            unsigned int iCnt = 0;
  170|      0|            for (unsigned int p = iBase; p < pcMesh->mNumFaces + iBase;++p) {
  ------------------
  |  Branch (170:42): [True: 0, False: 0]
  ------------------
  171|      0|                iCnt += pMesh->mFaces[p].mNumIndices;
  172|      0|            }
  173|      0|            pcMesh->mNumVertices = iCnt;
  174|       |
  175|       |            // allocate storage
  176|      0|            if (pMesh->mVertices != nullptr) {
  ------------------
  |  Branch (176:17): [True: 0, False: 0]
  ------------------
  177|      0|                pcMesh->mVertices = new aiVector3D[iCnt];
  178|      0|            }
  179|       |
  180|      0|            if (pMesh->HasNormals()) {
  ------------------
  |  Branch (180:17): [True: 0, False: 0]
  ------------------
  181|      0|                pcMesh->mNormals = new aiVector3D[iCnt];
  182|      0|            }
  183|       |
  184|      0|            if (pMesh->HasTangentsAndBitangents()) {
  ------------------
  |  Branch (184:17): [True: 0, False: 0]
  ------------------
  185|      0|                pcMesh->mTangents = new aiVector3D[iCnt];
  186|      0|                pcMesh->mBitangents = new aiVector3D[iCnt];
  187|      0|            }
  188|       |
  189|       |            // texture coordinates
  190|      0|            for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
  ------------------
  |  Branch (190:39): [True: 0, False: 0]
  ------------------
  191|      0|                pcMesh->mNumUVComponents[c] = pMesh->mNumUVComponents[c];
  192|      0|                if (pMesh->HasTextureCoords( c)) {
  ------------------
  |  Branch (192:21): [True: 0, False: 0]
  ------------------
  193|      0|                    pcMesh->mTextureCoords[c] = new aiVector3D[iCnt];
  194|      0|                }
  195|      0|            }
  196|       |
  197|       |            // vertex colors
  198|      0|            for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_COLOR_SETS;++c) {
  ------------------
  |  Branch (198:39): [True: 0, False: 0]
  ------------------
  199|      0|                if (pMesh->HasVertexColors( c)) {
  ------------------
  |  Branch (199:21): [True: 0, False: 0]
  ------------------
  200|      0|                    pcMesh->mColors[c] = new aiColor4D[iCnt];
  201|      0|                }
  202|      0|            }
  203|       |
  204|      0|            if (pMesh->HasBones()) {
  ------------------
  |  Branch (204:17): [True: 0, False: 0]
  ------------------
  205|       |                // assume the number of bones won't change in most cases
  206|      0|                pcMesh->mBones = new aiBone*[pMesh->mNumBones];
  207|       |
  208|       |                // iterate through all bones of the mesh and find those which
  209|       |                // need to be copied to the split mesh
  210|      0|                std::vector<aiVertexWeight> avTempWeights;
  211|      0|                for (unsigned int p = 0; p < pcMesh->mNumBones;++p) {
  ------------------
  |  Branch (211:42): [True: 0, False: 0]
  ------------------
  212|      0|                    aiBone* const bone = pcMesh->mBones[p];
  213|      0|                    avTempWeights.clear();
  214|      0|                    avTempWeights.reserve(bone->mNumWeights / iSubMeshes);
  215|       |
  216|      0|                    for (unsigned int q = 0; q < bone->mNumWeights;++q) {
  ------------------
  |  Branch (216:46): [True: 0, False: 0]
  ------------------
  217|      0|                        aiVertexWeight& weight = bone->mWeights[q];
  218|      0|                        if(weight.mVertexId >= iBase && weight.mVertexId < iBase + iOutVertexNum) {
  ------------------
  |  Branch (218:28): [True: 0, False: 0]
  |  Branch (218:57): [True: 0, False: 0]
  ------------------
  219|      0|                            avTempWeights.push_back(weight);
  220|      0|                            weight = avTempWeights.back();
  221|      0|                            weight.mVertexId -= iBase;
  222|      0|                        }
  223|      0|                    }
  224|       |
  225|      0|                    if (!avTempWeights.empty()) {
  ------------------
  |  Branch (225:25): [True: 0, False: 0]
  ------------------
  226|       |                        // we'll need this bone. Copy it ...
  227|      0|                        aiBone* pc = new aiBone();
  228|      0|                        pcMesh->mBones[pcMesh->mNumBones++] = pc;
  229|      0|                        pc->mName = aiString(bone->mName);
  230|      0|                        pc->mNumWeights = (unsigned int)avTempWeights.size();
  231|      0|                        pc->mOffsetMatrix = bone->mOffsetMatrix;
  232|       |
  233|       |                        // no need to reallocate the array for the last submesh.
  234|       |                        // Here we can reuse the (large) source array, although
  235|       |                        // we'll waste some memory
  236|      0|                        if (iSubMeshes-1 == i) {
  ------------------
  |  Branch (236:29): [True: 0, False: 0]
  ------------------
  237|      0|                            pc->mWeights = bone->mWeights;
  238|      0|                            bone->mWeights = nullptr;
  239|      0|                        } else {
  240|      0|                            pc->mWeights = new aiVertexWeight[pc->mNumWeights];
  241|      0|                        }
  242|       |
  243|       |                        // copy the weights
  244|      0|                        ::memcpy(pc->mWeights,&avTempWeights[0],sizeof(aiVertexWeight)*pc->mNumWeights);
  245|      0|                    }
  246|      0|                }
  247|      0|            }
  248|       |
  249|       |            // (we will also need to copy the array of indices)
  250|      0|            unsigned int iCurrent = 0;
  251|      0|            for (unsigned int p = 0; p < pcMesh->mNumFaces;++p) {
  ------------------
  |  Branch (251:38): [True: 0, False: 0]
  ------------------
  252|      0|                pcMesh->mFaces[p].mNumIndices = 3;
  253|       |                // allocate a new array
  254|      0|                const unsigned int iTemp = p + iBase;
  255|      0|                const unsigned int iNumIndices = pMesh->mFaces[iTemp].mNumIndices;
  256|       |
  257|       |                // setup face type and number of indices
  258|      0|                pcMesh->mFaces[p].mNumIndices = iNumIndices;
  259|      0|                unsigned int* pi = pMesh->mFaces[iTemp].mIndices;
  260|      0|                unsigned int* piOut = pcMesh->mFaces[p].mIndices = new unsigned int[iNumIndices];
  261|       |
  262|       |                // need to update the output primitive types
  263|      0|                switch (iNumIndices) {
  264|      0|                case 1:
  ------------------
  |  Branch (264:17): [True: 0, False: 0]
  ------------------
  265|      0|                    pcMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
  266|      0|                    break;
  267|      0|                case 2:
  ------------------
  |  Branch (267:17): [True: 0, False: 0]
  ------------------
  268|      0|                    pcMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
  269|      0|                    break;
  270|      0|                case 3:
  ------------------
  |  Branch (270:17): [True: 0, False: 0]
  ------------------
  271|      0|                    pcMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
  272|      0|                    break;
  273|      0|                default:
  ------------------
  |  Branch (273:17): [True: 0, False: 0]
  ------------------
  274|      0|                    pcMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
  275|      0|                }
  276|       |
  277|       |                // and copy the contents of the old array, offset by current base
  278|      0|                for (unsigned int v = 0; v < iNumIndices;++v) {
  ------------------
  |  Branch (278:42): [True: 0, False: 0]
  ------------------
  279|      0|                    unsigned int iIndex = pi[v];
  280|      0|                    unsigned int iIndexOut = iCurrent++;
  281|      0|                    piOut[v] = iIndexOut;
  282|       |
  283|       |                    // copy positions
  284|      0|                    if (pMesh->mVertices != nullptr) {
  ------------------
  |  Branch (284:25): [True: 0, False: 0]
  ------------------
  285|      0|                        pcMesh->mVertices[iIndexOut] = pMesh->mVertices[iIndex];
  286|      0|                    }
  287|       |
  288|       |                    // copy normals
  289|      0|                    if (pMesh->HasNormals()) {
  ------------------
  |  Branch (289:25): [True: 0, False: 0]
  ------------------
  290|      0|                        pcMesh->mNormals[iIndexOut] = pMesh->mNormals[iIndex];
  291|      0|                    }
  292|       |
  293|       |                    // copy tangents/bitangents
  294|      0|                    if (pMesh->HasTangentsAndBitangents()) {
  ------------------
  |  Branch (294:25): [True: 0, False: 0]
  ------------------
  295|      0|                        pcMesh->mTangents[iIndexOut] = pMesh->mTangents[iIndex];
  296|      0|                        pcMesh->mBitangents[iIndexOut] = pMesh->mBitangents[iIndex];
  297|      0|                    }
  298|       |
  299|       |                    // texture coordinates
  300|      0|                    for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
  ------------------
  |  Branch (300:47): [True: 0, False: 0]
  ------------------
  301|      0|                        if (pMesh->HasTextureCoords( c ) ) {
  ------------------
  |  Branch (301:29): [True: 0, False: 0]
  ------------------
  302|      0|                            pcMesh->mTextureCoords[c][iIndexOut] = pMesh->mTextureCoords[c][iIndex];
  303|      0|                        }
  304|      0|                    }
  305|       |                    // vertex colors
  306|      0|                    for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_COLOR_SETS;++c) {
  ------------------
  |  Branch (306:47): [True: 0, False: 0]
  ------------------
  307|      0|                        if (pMesh->HasVertexColors( c)) {
  ------------------
  |  Branch (307:29): [True: 0, False: 0]
  ------------------
  308|      0|                            pcMesh->mColors[c][iIndexOut] = pMesh->mColors[c][iIndex];
  309|      0|                        }
  310|      0|                    }
  311|      0|                }
  312|      0|            }
  313|       |
  314|       |            // add the newly created mesh to the list
  315|      0|            avList.emplace_back(pcMesh,a);
  316|      0|        }
  317|       |
  318|       |        // now delete the old mesh data
  319|      0|        delete pMesh;
  320|  2.11k|    } else {
  321|  2.11k|        avList.emplace_back(pMesh,a);
  322|  2.11k|    }
  323|  2.11k|}
_ZN6Assimp30SplitLargeMeshesProcess_VertexC2Ev:
  326|  3.48k|SplitLargeMeshesProcess_Vertex::SplitLargeMeshesProcess_Vertex() {
  327|       |    LIMIT = AI_SLM_DEFAULT_MAX_VERTICES;
  328|  3.48k|}
_ZNK6Assimp30SplitLargeMeshesProcess_Vertex8IsActiveEj:
  332|  1.43k|bool SplitLargeMeshesProcess_Vertex::IsActive( unsigned int pFlags) const {
  333|  1.43k|    return (pFlags & aiProcess_SplitLargeMeshes) != 0;
  334|  1.43k|}
_ZN6Assimp30SplitLargeMeshesProcess_Vertex7ExecuteEP7aiScene:
  338|  1.43k|void SplitLargeMeshesProcess_Vertex::Execute( aiScene* pScene) {
  339|  1.43k|    if (0xffffffff == this->LIMIT || nullptr == pScene ) {
  ------------------
  |  Branch (339:9): [True: 0, False: 1.43k]
  |  Branch (339:38): [True: 0, False: 1.43k]
  ------------------
  340|      0|        return;
  341|      0|    }
  342|       |
  343|  1.43k|    ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Vertex begin");
  344|       |
  345|  1.43k|    std::vector<std::pair<aiMesh*, unsigned int> > avList;
  346|       |
  347|       |    //Check for point cloud first,
  348|       |    //Do not process point cloud, splitMesh works only with faces data
  349|  2.83k|    for (unsigned int a = 0; a < pScene->mNumMeshes; a++) {
  ------------------
  |  Branch (349:30): [True: 1.80k, False: 1.03k]
  ------------------
  350|  1.80k|        if ( pScene->mMeshes[a]->mPrimitiveTypes == aiPrimitiveType_POINT ) {
  ------------------
  |  Branch (350:14): [True: 399, False: 1.40k]
  ------------------
  351|    399|            return;
  352|    399|        }
  353|  1.80k|    }
  354|       |
  355|  2.43k|    for( unsigned int a = 0; a < pScene->mNumMeshes; ++a ) {
  ------------------
  |  Branch (355:30): [True: 1.40k, False: 1.03k]
  ------------------
  356|  1.40k|        this->SplitMesh(a, pScene->mMeshes[a], avList);
  357|  1.40k|    }
  358|       |
  359|  1.03k|    if (avList.size() != pScene->mNumMeshes) {
  ------------------
  |  Branch (359:9): [True: 0, False: 1.03k]
  ------------------
  360|       |        // it seems something has been split. rebuild the mesh list
  361|      0|        delete[] pScene->mMeshes;
  362|      0|        pScene->mNumMeshes = (unsigned int)avList.size();
  363|      0|        pScene->mMeshes = new aiMesh*[avList.size()];
  364|       |
  365|      0|        for (unsigned int i = 0; i < avList.size();++i) {
  ------------------
  |  Branch (365:34): [True: 0, False: 0]
  ------------------
  366|      0|            pScene->mMeshes[i] = avList[i].first;
  367|      0|        }
  368|       |
  369|       |        // now we need to update all nodes
  370|      0|        SplitLargeMeshesProcess_Triangle::UpdateNode(pScene->mRootNode,avList);
  371|      0|        ASSIMP_LOG_INFO("SplitLargeMeshesProcess_Vertex finished. Meshes have been split");
  372|  1.03k|    } else {
  373|       |        ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Vertex finished. There was nothing to do");
  374|  1.03k|    }
  375|  1.03k|}
_ZN6Assimp30SplitLargeMeshesProcess_Vertex15SetupPropertiesEPKNS_8ImporterE:
  379|  1.43k|void SplitLargeMeshesProcess_Vertex::SetupProperties( const Importer* pImp) {
  380|  1.43k|    this->LIMIT = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT,AI_SLM_DEFAULT_MAX_VERTICES);
  381|  1.43k|}
_ZN6Assimp30SplitLargeMeshesProcess_Vertex9SplitMeshEjP6aiMeshRNSt3__16vectorINS3_4pairIS2_jEENS3_9allocatorIS6_EEEE:
  388|  1.40k|        std::vector<std::pair<aiMesh*, unsigned int> >& avList) {
  389|  1.40k|    if (pMesh->mNumVertices > SplitLargeMeshesProcess_Vertex::LIMIT) {
  ------------------
  |  Branch (389:9): [True: 0, False: 1.40k]
  ------------------
  390|      0|        typedef std::vector< std::pair<unsigned int,float> > VertexWeightTable;
  391|       |
  392|       |        // build a per-vertex weight list if necessary
  393|      0|        VertexWeightTable* avPerVertexWeights = ComputeVertexBoneWeightTable(pMesh);
  394|       |
  395|       |        // we need to split this mesh into sub meshes
  396|       |        // determine the estimated size of a submesh
  397|       |        // (this could be too large. Max waste is a single digit percentage)
  398|      0|        const unsigned int iSubMeshes = (pMesh->mNumVertices / SplitLargeMeshesProcess_Vertex::LIMIT) + 1;
  399|       |
  400|       |        // create a std::vector<unsigned int> to indicate which vertices
  401|       |        // have already been copied
  402|      0|        std::vector<unsigned int> avWasCopied;
  403|      0|        avWasCopied.resize(pMesh->mNumVertices,0xFFFFFFFF);
  404|       |
  405|       |        // try to find a good estimate for the number of output faces
  406|       |        // per mesh. Add 12.5% as buffer
  407|      0|        unsigned int iEstimatedSize = pMesh->mNumFaces / iSubMeshes;
  408|      0|        iEstimatedSize += iEstimatedSize >> 3;
  409|       |
  410|       |        // now generate all submeshes
  411|      0|        unsigned int iBase( 0 );
  412|      0|        while (true) {
  ------------------
  |  Branch (412:16): [True: 0, Folded]
  ------------------
  413|      0|            const unsigned int iOutVertexNum = SplitLargeMeshesProcess_Vertex::LIMIT;
  414|      0|            aiMesh* pcMesh          = new aiMesh;
  415|      0|            pcMesh->mNumVertices    = 0;
  416|      0|            pcMesh->mMaterialIndex  = pMesh->mMaterialIndex;
  417|       |
  418|       |            // the name carries the adjacency information between the meshes
  419|      0|            pcMesh->mName = pMesh->mName;
  420|       |
  421|      0|            typedef std::vector<aiVertexWeight> BoneWeightList;
  422|      0|            if (pMesh->HasBones()) {
  ------------------
  |  Branch (422:17): [True: 0, False: 0]
  ------------------
  423|      0|                pcMesh->mBones = new aiBone*[pMesh->mNumBones];
  424|      0|                ::memset(pcMesh->mBones,0,sizeof(void*)*pMesh->mNumBones);
  425|      0|            }
  426|       |
  427|       |            // clear the temporary helper array
  428|      0|            if (iBase) {
  ------------------
  |  Branch (428:17): [True: 0, False: 0]
  ------------------
  429|       |                // we can't use memset here we unsigned int needn' be 32 bits
  430|      0|                for (auto &elem : avWasCopied) {
  ------------------
  |  Branch (430:33): [True: 0, False: 0]
  ------------------
  431|      0|                    elem = 0xffffffff;
  432|      0|                }
  433|      0|            }
  434|       |
  435|       |            // output vectors
  436|      0|            std::vector<aiFace> vFaces;
  437|       |
  438|       |            // reserve enough storage for most cases
  439|      0|            if (pMesh->HasPositions()) {
  ------------------
  |  Branch (439:17): [True: 0, False: 0]
  ------------------
  440|      0|                pcMesh->mVertices = new aiVector3D[iOutVertexNum];
  441|      0|            }
  442|      0|            if (pMesh->HasNormals()) {
  ------------------
  |  Branch (442:17): [True: 0, False: 0]
  ------------------
  443|      0|                pcMesh->mNormals = new aiVector3D[iOutVertexNum];
  444|      0|            }
  445|      0|            if (pMesh->HasTangentsAndBitangents()) {
  ------------------
  |  Branch (445:17): [True: 0, False: 0]
  ------------------
  446|      0|                pcMesh->mTangents = new aiVector3D[iOutVertexNum];
  447|      0|                pcMesh->mBitangents = new aiVector3D[iOutVertexNum];
  448|      0|            }
  449|      0|            for (unsigned int c = 0; pMesh->HasVertexColors(c);++c) {
  ------------------
  |  Branch (449:38): [True: 0, False: 0]
  ------------------
  450|      0|                pcMesh->mColors[c] = new aiColor4D[iOutVertexNum];
  451|      0|            }
  452|      0|            for (unsigned int c = 0; pMesh->HasTextureCoords(c);++c) {
  ------------------
  |  Branch (452:38): [True: 0, False: 0]
  ------------------
  453|      0|                pcMesh->mNumUVComponents[c] = pMesh->mNumUVComponents[c];
  454|      0|                pcMesh->mTextureCoords[c] = new aiVector3D[iOutVertexNum];
  455|      0|            }
  456|      0|            vFaces.reserve(iEstimatedSize);
  457|       |
  458|       |            // (we will also need to copy the array of indices)
  459|      0|            while (iBase < pMesh->mNumFaces) {
  ------------------
  |  Branch (459:20): [True: 0, False: 0]
  ------------------
  460|       |                // allocate a new array
  461|      0|                const unsigned int iNumIndices = pMesh->mFaces[iBase].mNumIndices;
  462|       |
  463|       |                // doesn't catch degenerates but is quite fast
  464|      0|                unsigned int iNeed = 0;
  465|      0|                for (unsigned int v = 0; v < iNumIndices;++v) {
  ------------------
  |  Branch (465:42): [True: 0, False: 0]
  ------------------
  466|      0|                    unsigned int iIndex = pMesh->mFaces[iBase].mIndices[v];
  467|       |
  468|       |                    // check whether we do already have this vertex
  469|      0|                    if (0xFFFFFFFF == avWasCopied[iIndex]) {
  ------------------
  |  Branch (469:25): [True: 0, False: 0]
  ------------------
  470|      0|                        iNeed++;
  471|      0|                    }
  472|      0|                }
  473|      0|                if (pcMesh->mNumVertices + iNeed > iOutVertexNum) {
  ------------------
  |  Branch (473:21): [True: 0, False: 0]
  ------------------
  474|       |                    // don't use this face
  475|      0|                    break;
  476|      0|                }
  477|       |
  478|      0|                vFaces.emplace_back();
  479|      0|                aiFace& rFace = vFaces.back();
  480|       |
  481|       |                // setup face type and number of indices
  482|      0|                rFace.mNumIndices = iNumIndices;
  483|      0|                rFace.mIndices = new unsigned int[iNumIndices];
  484|       |
  485|       |                // need to update the output primitive types
  486|      0|                switch (rFace.mNumIndices) {
  487|      0|                case 1:
  ------------------
  |  Branch (487:17): [True: 0, False: 0]
  ------------------
  488|      0|                    pcMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
  489|      0|                    break;
  490|      0|                case 2:
  ------------------
  |  Branch (490:17): [True: 0, False: 0]
  ------------------
  491|      0|                    pcMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
  492|      0|                    break;
  493|      0|                case 3:
  ------------------
  |  Branch (493:17): [True: 0, False: 0]
  ------------------
  494|      0|                    pcMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
  495|      0|                    break;
  496|      0|                default:
  ------------------
  |  Branch (496:17): [True: 0, False: 0]
  ------------------
  497|      0|                    pcMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
  498|      0|                }
  499|       |
  500|       |                // and copy the contents of the old array, offset by current base
  501|      0|                for (unsigned int v = 0; v < iNumIndices;++v) {
  ------------------
  |  Branch (501:42): [True: 0, False: 0]
  ------------------
  502|      0|                    unsigned int iIndex = pMesh->mFaces[iBase].mIndices[v];
  503|       |
  504|       |                    // check whether we do already have this vertex
  505|      0|                    if (0xFFFFFFFF != avWasCopied[iIndex]) {
  ------------------
  |  Branch (505:25): [True: 0, False: 0]
  ------------------
  506|      0|                        rFace.mIndices[v] = avWasCopied[iIndex];
  507|      0|                        continue;
  508|      0|                    }
  509|       |
  510|       |                    // copy positions
  511|      0|                    pcMesh->mVertices[pcMesh->mNumVertices] = (pMesh->mVertices[iIndex]);
  512|       |
  513|       |                    // copy normals
  514|      0|                    if (pMesh->HasNormals()) {
  ------------------
  |  Branch (514:25): [True: 0, False: 0]
  ------------------
  515|      0|                        pcMesh->mNormals[pcMesh->mNumVertices] = (pMesh->mNormals[iIndex]);
  516|      0|                    }
  517|       |
  518|       |                    // copy tangents/bitangents
  519|      0|                    if (pMesh->HasTangentsAndBitangents()) {
  ------------------
  |  Branch (519:25): [True: 0, False: 0]
  ------------------
  520|      0|                        pcMesh->mTangents[pcMesh->mNumVertices] = (pMesh->mTangents[iIndex]);
  521|      0|                        pcMesh->mBitangents[pcMesh->mNumVertices] = (pMesh->mBitangents[iIndex]);
  522|      0|                    }
  523|       |
  524|       |                    // texture coordinates
  525|      0|                    for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
  ------------------
  |  Branch (525:47): [True: 0, False: 0]
  ------------------
  526|      0|                        if (pMesh->HasTextureCoords( c)) {
  ------------------
  |  Branch (526:29): [True: 0, False: 0]
  ------------------
  527|      0|                            pcMesh->mTextureCoords[c][pcMesh->mNumVertices] = pMesh->mTextureCoords[c][iIndex];
  528|      0|                        }
  529|      0|                    }
  530|       |                    // vertex colors
  531|      0|                    for (unsigned int c = 0;  c < AI_MAX_NUMBER_OF_COLOR_SETS;++c) {
  ------------------
  |  Branch (531:47): [True: 0, False: 0]
  ------------------
  532|      0|                        if (pMesh->HasVertexColors( c)) {
  ------------------
  |  Branch (532:29): [True: 0, False: 0]
  ------------------
  533|      0|                            pcMesh->mColors[c][pcMesh->mNumVertices] = pMesh->mColors[c][iIndex];
  534|      0|                        }
  535|      0|                    }
  536|       |                    // check whether we have bone weights assigned to this vertex
  537|      0|                    rFace.mIndices[v] = pcMesh->mNumVertices;
  538|      0|                    if (avPerVertexWeights) {
  ------------------
  |  Branch (538:25): [True: 0, False: 0]
  ------------------
  539|      0|                        VertexWeightTable& table = avPerVertexWeights[ pcMesh->mNumVertices ];
  540|      0|                        if( !table.empty() ) {
  ------------------
  |  Branch (540:29): [True: 0, False: 0]
  ------------------
  541|      0|                            for (VertexWeightTable::const_iterator iter =  table.begin();
  542|      0|                                    iter != table.end();++iter) {
  ------------------
  |  Branch (542:37): [True: 0, False: 0]
  ------------------
  543|       |                                // allocate the bone weight array if necessary
  544|      0|                                BoneWeightList* pcWeightList = (BoneWeightList*)pcMesh->mBones[(*iter).first];
  545|      0|                                if (nullptr == pcWeightList) {
  ------------------
  |  Branch (545:37): [True: 0, False: 0]
  ------------------
  546|      0|                                    pcMesh->mBones[(*iter).first] = (aiBone*)(pcWeightList = new BoneWeightList());
  547|      0|                                }
  548|      0|                                pcWeightList->push_back(aiVertexWeight(pcMesh->mNumVertices,(*iter).second));
  549|      0|                            }
  550|      0|                        }
  551|      0|                    }
  552|       |
  553|      0|                    avWasCopied[iIndex] = pcMesh->mNumVertices;
  554|      0|                    pcMesh->mNumVertices++;
  555|      0|                }
  556|      0|                ++iBase;
  557|      0|                if(pcMesh->mNumVertices == iOutVertexNum) {
  ------------------
  |  Branch (557:20): [True: 0, False: 0]
  ------------------
  558|       |                    // break here. The face is only added if it was complete
  559|      0|                    break;
  560|      0|                }
  561|      0|            }
  562|       |
  563|       |            // check which bones we'll need to create for this submesh
  564|      0|            if (pMesh->HasBones()) {
  ------------------
  |  Branch (564:17): [True: 0, False: 0]
  ------------------
  565|      0|                aiBone** ppCurrent = pcMesh->mBones;
  566|      0|                for (unsigned int k = 0; k < pMesh->mNumBones;++k) {
  ------------------
  |  Branch (566:42): [True: 0, False: 0]
  ------------------
  567|       |                    // check whether the bone is existing
  568|      0|                    BoneWeightList* pcWeightList;
  569|      0|                    pcWeightList = (BoneWeightList *)pcMesh->mBones[k];
  570|      0|                    if (nullptr != pcWeightList) {
  ------------------
  |  Branch (570:25): [True: 0, False: 0]
  ------------------
  571|      0|                        aiBone *pcOldBone = pMesh->mBones[k];
  572|      0|                        aiBone* pcOut( nullptr );
  573|      0|                        *ppCurrent++ = pcOut = new aiBone();
  574|      0|                        pcOut->mName = aiString(pcOldBone->mName);
  575|      0|                        pcOut->mOffsetMatrix = pcOldBone->mOffsetMatrix;
  576|      0|                        pcOut->mNumWeights = (unsigned int)pcWeightList->size();
  577|      0|                        pcOut->mWeights = new aiVertexWeight[pcOut->mNumWeights];
  578|       |
  579|       |                        // copy the vertex weights
  580|      0|                        ::memcpy(pcOut->mWeights,&pcWeightList->operator[](0),
  581|      0|                            pcOut->mNumWeights * sizeof(aiVertexWeight));
  582|       |
  583|       |                        // delete the temporary bone weight list
  584|      0|                        delete pcWeightList;
  585|      0|                        pcMesh->mNumBones++;
  586|      0|                    }
  587|      0|                }
  588|      0|            }
  589|       |
  590|       |            // copy the face list to the mesh
  591|      0|            pcMesh->mFaces = new aiFace[vFaces.size()];
  592|      0|            pcMesh->mNumFaces = (unsigned int)vFaces.size();
  593|       |
  594|      0|            for (unsigned int p = 0; p < pcMesh->mNumFaces;++p) {
  ------------------
  |  Branch (594:38): [True: 0, False: 0]
  ------------------
  595|      0|                pcMesh->mFaces[p] = vFaces[p];
  596|      0|            }
  597|       |
  598|       |            // add the newly created mesh to the list
  599|      0|            avList.emplace_back(pcMesh,a);
  600|       |
  601|      0|            if (iBase == pMesh->mNumFaces) {
  ------------------
  |  Branch (601:17): [True: 0, False: 0]
  ------------------
  602|       |                // have all faces ... finish the outer loop, too
  603|      0|                break;
  604|      0|            }
  605|      0|        }
  606|       |
  607|       |        // delete the per-vertex weight list again
  608|      0|        delete[] avPerVertexWeights;
  609|       |
  610|       |        // now delete the old mesh data
  611|      0|        delete pMesh;
  612|      0|        return;
  613|      0|    }
  614|  1.40k|    avList.emplace_back(pMesh,a);
  615|  1.40k|}

_ZNK6Assimp20TextureTransformStep8IsActiveEj:
   54|  1.48k|bool TextureTransformStep::IsActive( unsigned int pFlags) const {
   55|  1.48k|    return  (pFlags & aiProcess_TransformUVCoords) != 0;
   56|  1.48k|}

_ZN6Assimp20TextureTransformStepC2Ev:
  172|  3.48k|    TextureTransformStep() = default;

_ZNK6Assimp18TriangulateProcess8IsActiveEj:
  179|  1.48k|bool TriangulateProcess::IsActive( unsigned int pFlags) const {
  180|  1.48k|    return (pFlags & aiProcess_Triangulate) != 0;
  181|  1.48k|}
_ZN6Assimp18TriangulateProcess7ExecuteEP7aiScene:
  185|  1.48k|void TriangulateProcess::Execute( aiScene* pScene) {
  186|  1.48k|    ASSIMP_LOG_DEBUG("TriangulateProcess begin");
  187|       |
  188|  1.48k|    bool bHas = false;
  189|  2.81k|    for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
  ------------------
  |  Branch (189:30): [True: 1.32k, False: 1.48k]
  ------------------
  190|  1.32k|    {
  191|  1.32k|        if (pScene->mMeshes[ a ]) {
  ------------------
  |  Branch (191:13): [True: 1.32k, False: 0]
  ------------------
  192|  1.32k|            if ( TriangulateMesh( pScene->mMeshes[ a ] ) ) {
  ------------------
  |  Branch (192:18): [True: 0, False: 1.32k]
  ------------------
  193|      0|                bHas = true;
  194|      0|            }
  195|  1.32k|        }
  196|  1.32k|    }
  197|  1.48k|    if ( bHas ) {
  ------------------
  |  Branch (197:10): [True: 0, False: 1.48k]
  ------------------
  198|      0|        ASSIMP_LOG_INFO( "TriangulateProcess finished. All polygons have been triangulated." );
  199|  1.48k|    } else {
  200|       |        ASSIMP_LOG_DEBUG( "TriangulateProcess finished. There was nothing to be done." );
  201|  1.48k|    }
  202|  1.48k|}
_ZN6Assimp18TriangulateProcess15TriangulateMeshEP6aiMesh:
  206|  1.32k|bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) {
  207|       |    // Now we have aiMesh::mPrimitiveTypes, so this is only here for test cases
  208|  1.32k|    if (!pMesh->mPrimitiveTypes)    {
  ------------------
  |  Branch (208:9): [True: 0, False: 1.32k]
  ------------------
  209|      0|        bool bNeed = false;
  210|       |
  211|      0|        for( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
  ------------------
  |  Branch (211:34): [True: 0, False: 0]
  ------------------
  212|      0|            const aiFace& face = pMesh->mFaces[a];
  213|      0|            if( face.mNumIndices != 3)  {
  ------------------
  |  Branch (213:17): [True: 0, False: 0]
  ------------------
  214|      0|                bNeed = true;
  215|      0|            }
  216|      0|        }
  217|      0|        if (!bNeed) {
  ------------------
  |  Branch (217:13): [True: 0, False: 0]
  ------------------
  218|      0|            return false;
  219|      0|        }
  220|      0|    }
  221|  1.32k|    else if (!(pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON)) {
  ------------------
  |  Branch (221:14): [True: 1.32k, False: 0]
  ------------------
  222|  1.32k|        return false;
  223|  1.32k|    }
  224|       |
  225|       |    // Find out how many output faces we'll get
  226|      0|    uint32_t numOut = 0, max_out = 0;
  227|      0|    bool get_normals = true;
  228|      0|    for( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
  ------------------
  |  Branch (228:30): [True: 0, False: 0]
  ------------------
  229|      0|        aiFace& face = pMesh->mFaces[a];
  230|      0|        if (face.mNumIndices <= 4) {
  ------------------
  |  Branch (230:13): [True: 0, False: 0]
  ------------------
  231|      0|            get_normals = false;
  232|      0|        }
  233|      0|        if( face.mNumIndices <= 3) {
  ------------------
  |  Branch (233:13): [True: 0, False: 0]
  ------------------
  234|      0|            ++numOut;
  235|      0|        } else {
  236|      0|            numOut += face.mNumIndices-2;
  237|      0|            max_out = std::max<uint32_t>(max_out,face.mNumIndices);
  238|      0|        }
  239|      0|    }
  240|       |
  241|       |    // Just another check whether aiMesh::mPrimitiveTypes is correct
  242|      0|    if (numOut == pMesh->mNumFaces) {
  ------------------
  |  Branch (242:9): [True: 0, False: 0]
  ------------------
  243|      0|        ASSIMP_LOG_ERROR( "Invalidation detected in the number of indices: does not fit to the primitive type." );
  244|      0|        return false;
  245|      0|    }
  246|       |
  247|      0|    aiVector3D *nor_out = nullptr;
  248|       |
  249|       |    // if we don't have normals yet, but expect them to be a cheap side
  250|       |    // product of triangulation anyway, allocate storage for them.
  251|      0|    if (!pMesh->mNormals && get_normals) {
  ------------------
  |  Branch (251:9): [True: 0, False: 0]
  |  Branch (251:29): [True: 0, False: 0]
  ------------------
  252|       |        // XXX need a mechanism to inform the GenVertexNormals process to treat these normals as preprocessed per-face normals
  253|       |    //  nor_out = pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
  254|      0|    }
  255|       |
  256|       |    // the output mesh will contain triangles, but no polys anymore
  257|      0|    pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
  258|      0|    pMesh->mPrimitiveTypes &= ~aiPrimitiveType_POLYGON;
  259|       |
  260|       |    // The mesh becomes NGON encoded now, during the triangulation process.
  261|      0|    pMesh->mPrimitiveTypes |= aiPrimitiveType_NGONEncodingFlag;
  262|       |
  263|      0|    aiFace* out = new aiFace[numOut](), *curOut = out;
  264|      0|    std::vector<aiVector3D> temp_verts3d(max_out+2); /* temporary storage for vertices */
  265|      0|    std::vector<std::vector<aiVector2D>> temp_poly(1); /* temporary storage for earcut.hpp */
  266|      0|    std::vector<aiVector2D>& temp_verts = temp_poly[0];
  267|      0|    temp_verts.reserve(max_out + 2);
  268|       |
  269|      0|    NGONEncoder ngonEncoder;
  270|       |
  271|       |    // Apply vertex colors to represent the face winding?
  272|       |#ifdef AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING
  273|       |    if (!pMesh->mColors[0])
  274|       |        pMesh->mColors[0] = new aiColor4D[pMesh->mNumVertices];
  275|       |    else
  276|       |        new(pMesh->mColors[0]) aiColor4D[pMesh->mNumVertices];
  277|       |
  278|       |    aiColor4D* clr = pMesh->mColors[0];
  279|       |#endif
  280|       |
  281|       |#ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS
  282|       |    FILE* fout = fopen(POLY_OUTPUT_FILE,"a");
  283|       |#endif
  284|       |
  285|      0|    const aiVector3D* verts = pMesh->mVertices;
  286|       |
  287|      0|    for( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
  ------------------
  |  Branch (287:30): [True: 0, False: 0]
  ------------------
  288|      0|        aiFace& face = pMesh->mFaces[a];
  289|       |
  290|      0|        unsigned int* idx = face.mIndices;
  291|      0|        unsigned int num = face.mNumIndices;
  292|       |
  293|       |        // Apply vertex colors to represent the face winding?
  294|       |#ifdef AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING
  295|       |        for (unsigned int i = 0; i < face.mNumIndices; ++i) {
  296|       |            aiColor4D& c = clr[idx[i]];
  297|       |            c.r = (i+1) / (float)max;
  298|       |            c.b = 1.f - c.r;
  299|       |        }
  300|       |#endif
  301|       |
  302|      0|        aiFace* const last_face = curOut;
  303|       |
  304|       |        // if it's a simple point,line or triangle: just copy it
  305|      0|        if( face.mNumIndices <= 3)
  ------------------
  |  Branch (305:13): [True: 0, False: 0]
  ------------------
  306|      0|        {
  307|      0|            aiFace& nface = *curOut++;
  308|      0|            nface.mNumIndices = face.mNumIndices;
  309|      0|            nface.mIndices    = face.mIndices;
  310|      0|            face.mIndices = nullptr;
  311|       |
  312|       |            // points and lines don't require ngon encoding (and are not supported either!)
  313|      0|            if (nface.mNumIndices == 3) ngonEncoder.ngonEncodeTriangle(&nface);
  ------------------
  |  Branch (313:17): [True: 0, False: 0]
  ------------------
  314|       |
  315|      0|            continue;
  316|      0|        }
  317|       |        // optimized code for quadrilaterals
  318|      0|        else if ( face.mNumIndices == 4) {
  ------------------
  |  Branch (318:19): [True: 0, False: 0]
  ------------------
  319|       |
  320|       |            // quads can have at maximum one concave vertex. Determine
  321|       |            // this vertex (if it exists) and start tri-fanning from
  322|       |            // it.
  323|      0|            unsigned int start_vertex = 0;
  324|      0|            for (unsigned int i = 0; i < 4; ++i) {
  ------------------
  |  Branch (324:38): [True: 0, False: 0]
  ------------------
  325|      0|                const aiVector3D& v0 = verts[face.mIndices[(i+3) % 4]];
  326|      0|                const aiVector3D& v1 = verts[face.mIndices[(i+2) % 4]];
  327|      0|                const aiVector3D& v2 = verts[face.mIndices[(i+1) % 4]];
  328|       |
  329|      0|                const aiVector3D& v = verts[face.mIndices[i]];
  330|       |
  331|      0|                aiVector3D left = (v0-v);
  332|      0|                aiVector3D diag = (v1-v);
  333|      0|                aiVector3D right = (v2-v);
  334|       |
  335|      0|                left.Normalize();
  336|      0|                diag.Normalize();
  337|      0|                right.Normalize();
  338|       |
  339|      0|                const float angle = std::acos(left*diag) + std::acos(right*diag);
  340|      0|                if (angle > AI_MATH_PI_F) {
  ------------------
  |  Branch (340:21): [True: 0, False: 0]
  ------------------
  341|       |                    // this is the concave point
  342|      0|                    start_vertex = i;
  343|      0|                    break;
  344|      0|                }
  345|      0|            }
  346|       |
  347|      0|            const unsigned int temp[] = {face.mIndices[0], face.mIndices[1], face.mIndices[2], face.mIndices[3]};
  348|       |
  349|      0|            aiFace& nface = *curOut++;
  350|      0|            nface.mNumIndices = 3;
  351|      0|            nface.mIndices = face.mIndices;
  352|       |
  353|      0|            nface.mIndices[0] = temp[start_vertex];
  354|      0|            nface.mIndices[1] = temp[(start_vertex + 1) % 4];
  355|      0|            nface.mIndices[2] = temp[(start_vertex + 2) % 4];
  356|       |
  357|      0|            aiFace& sface = *curOut++;
  358|      0|            sface.mNumIndices = 3;
  359|      0|            sface.mIndices = new unsigned int[3];
  360|       |
  361|      0|            sface.mIndices[0] = temp[start_vertex];
  362|      0|            sface.mIndices[1] = temp[(start_vertex + 2) % 4];
  363|      0|            sface.mIndices[2] = temp[(start_vertex + 3) % 4];
  364|       |
  365|       |            // prevent double deletion of the indices field
  366|      0|            face.mIndices = nullptr;
  367|       |
  368|      0|            ngonEncoder.ngonEncodeQuad(&nface, &sface);
  369|       |
  370|      0|            continue;
  371|      0|        }
  372|      0|        else
  373|      0|        {
  374|       |            // A polygon with more than 3 vertices can be either concave or convex.
  375|       |            // Usually everything we're getting is convex and we could easily
  376|       |            // triangulate by tri-fanning. However, LightWave is probably the only
  377|       |            // modeling suite to make extensive use of highly concave, monster polygons ...
  378|       |            // so we need to apply the full 'ear cutting' algorithm to get it right.
  379|       |
  380|       |            // REQUIREMENT: polygon is expected to be simple and *nearly* planar.
  381|       |            // We project it onto a plane to get a 2d triangle.
  382|       |
  383|       |            // Collect all vertices of of the polygon.
  384|      0|            for (unsigned int tmp = 0; tmp < num; ++tmp) {
  ------------------
  |  Branch (384:40): [True: 0, False: 0]
  ------------------
  385|      0|                temp_verts3d[tmp] = verts[idx[tmp]];
  386|      0|            }
  387|       |
  388|       |            // Get newell normal of the polygon. Store it for future use if it's a polygon-only mesh
  389|      0|            aiVector3D n;
  390|      0|            NewellNormal<3, 3, 3>(n, num, &temp_verts3d.front().x, &temp_verts3d.front().y, &temp_verts3d.front().z);
  391|      0|            if (nor_out) {
  ------------------
  |  Branch (391:17): [True: 0, False: 0]
  ------------------
  392|      0|                for (unsigned int tmp = 0; tmp < num; ++tmp)
  ------------------
  |  Branch (392:44): [True: 0, False: 0]
  ------------------
  393|      0|                    nor_out[idx[tmp]] = n;
  394|      0|            }
  395|       |
  396|       |            // Select largest normal coordinate to ignore for projection
  397|      0|            const float ax = (n.x>0 ? n.x : -n.x);
  ------------------
  |  Branch (397:31): [True: 0, False: 0]
  ------------------
  398|      0|            const float ay = (n.y>0 ? n.y : -n.y);
  ------------------
  |  Branch (398:31): [True: 0, False: 0]
  ------------------
  399|      0|            const float az = (n.z>0 ? n.z : -n.z);
  ------------------
  |  Branch (399:31): [True: 0, False: 0]
  ------------------
  400|       |
  401|      0|            unsigned int ac = 0, bc = 1; /* no z coord. projection to xy */
  402|      0|            float inv = n.z;
  403|      0|            if (ax > ay) {
  ------------------
  |  Branch (403:17): [True: 0, False: 0]
  ------------------
  404|      0|                if (ax > az) { /* no x coord. projection to yz */
  ------------------
  |  Branch (404:21): [True: 0, False: 0]
  ------------------
  405|      0|                    ac = 1; bc = 2;
  406|      0|                    inv = n.x;
  407|      0|                }
  408|      0|            }
  409|      0|            else if (ay > az) { /* no y coord. projection to zy */
  ------------------
  |  Branch (409:22): [True: 0, False: 0]
  ------------------
  410|      0|                ac = 2; bc = 0;
  411|      0|                inv = n.y;
  412|      0|            }
  413|       |
  414|       |            // Swap projection axes to take the negated projection vector into account
  415|      0|            if (inv < 0.f) {
  ------------------
  |  Branch (415:17): [True: 0, False: 0]
  ------------------
  416|      0|                std::swap(ac,bc);
  417|      0|            }
  418|       |
  419|      0|            temp_verts.resize(num);
  420|      0|            for (unsigned int tmp = 0; tmp < num; ++tmp) {
  ------------------
  |  Branch (420:40): [True: 0, False: 0]
  ------------------
  421|      0|                temp_verts[tmp].x = verts[idx[tmp]][ac];
  422|      0|                temp_verts[tmp].y = verts[idx[tmp]][bc];
  423|      0|            }
  424|       |
  425|      0|            auto indices = mapbox::earcut(temp_poly);
  426|      0|            for (size_t i = 0; i < indices.size(); i += 3) {
  ------------------
  |  Branch (426:32): [True: 0, False: 0]
  ------------------
  427|      0|                aiFace& nface = *curOut++;
  428|      0|                nface.mIndices = new unsigned int[3];
  429|      0|                nface.mNumIndices = 3;
  430|      0|                nface.mIndices[0] = indices[i];
  431|      0|                nface.mIndices[1] = indices[i + 1];
  432|      0|                nface.mIndices[2] = indices[i + 2];
  433|      0|            }
  434|       |
  435|       |#ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS
  436|       |            // plot the plane onto which we mapped the polygon to a 2D ASCII pic
  437|       |            aiVector2D bmin,bmax;
  438|       |            ArrayBounds(&temp_verts[0],max,bmin,bmax);
  439|       |
  440|       |            char grid[POLY_GRID_Y][POLY_GRID_X+POLY_GRID_XPAD];
  441|       |            std::fill_n((char*)grid,POLY_GRID_Y*(POLY_GRID_X+POLY_GRID_XPAD),' ');
  442|       |
  443|       |            for (int i =0; i < max; ++i) {
  444|       |                const aiVector2D& v = (temp_verts[i] - bmin) / (bmax-bmin);
  445|       |                const size_t x = static_cast<size_t>(v.x*(POLY_GRID_X-1)), y = static_cast<size_t>(v.y*(POLY_GRID_Y-1));
  446|       |                char* loc = grid[y]+x;
  447|       |                if (grid[y][x] != ' ') {
  448|       |                    for(;*loc != ' '; ++loc);
  449|       |                    *loc++ = '_';
  450|       |                }
  451|       |                *(loc+::ai_snprintf(loc, POLY_GRID_XPAD,"%i",i)) = ' ';
  452|       |            }
  453|       |
  454|       |
  455|       |            for(size_t y = 0; y < POLY_GRID_Y; ++y) {
  456|       |                grid[y][POLY_GRID_X+POLY_GRID_XPAD-1] = '\0';
  457|       |                fprintf(fout,"%s\n",grid[y]);
  458|       |            }
  459|       |
  460|       |            fprintf(fout,"\ntriangulation sequence: ");
  461|       |#endif
  462|      0|        }
  463|       |
  464|       |#ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS
  465|       |
  466|       |        for(aiFace* f = last_face; f != curOut; ++f) {
  467|       |            unsigned int* i = f->mIndices;
  468|       |            fprintf(fout," (%i %i %i)",i[0],i[1],i[2]);
  469|       |        }
  470|       |
  471|       |        fprintf(fout,"\n*********************************************************************\n");
  472|       |        fflush(fout);
  473|       |
  474|       |#endif
  475|       |
  476|      0|        for(aiFace* f = last_face; f != curOut; ) {
  ------------------
  |  Branch (476:36): [True: 0, False: 0]
  ------------------
  477|      0|            unsigned int* i = f->mIndices;
  478|       |
  479|      0|            i[0] = idx[i[0]];
  480|      0|            i[1] = idx[i[1]];
  481|      0|            i[2] = idx[i[2]];
  482|       |
  483|       |            // IMPROVEMENT: Polygons are not supported yet by this ngon encoding + triangulation step.
  484|       |            //              So we encode polygons as regular triangles. No way to reconstruct the original
  485|       |            //              polygon in this case.
  486|      0|            ngonEncoder.ngonEncodeTriangle(f);
  487|      0|            ++f;
  488|      0|        }
  489|       |
  490|      0|        delete[] face.mIndices;
  491|      0|        face.mIndices = nullptr;
  492|      0|    }
  493|       |
  494|       |#ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS
  495|       |    fclose(fout);
  496|       |#endif
  497|       |
  498|       |    // kill the old faces
  499|      0|    delete [] pMesh->mFaces;
  500|       |
  501|       |    // ... and store the new ones
  502|      0|    pMesh->mFaces    = out;
  503|      0|    pMesh->mNumFaces = (unsigned int)(curOut-out); /* not necessarily equal to numOut */
  504|      0|    return true;
  505|      0|}

_ZN6Assimp18TriangulateProcessC2Ev:
   65|  3.48k|    TriangulateProcess() = default;

_ZN6Assimp17ValidateDSProcessC2Ev:
   61|  1.62k|ValidateDSProcess::ValidateDSProcess() : mScene(nullptr) {}
_ZN6Assimp17ValidateDSProcess11ReportErrorEPKcz:
   69|    139|AI_WONT_RETURN void ValidateDSProcess::ReportError(const char *msg, ...) {
   70|    139|    ai_assert(nullptr != msg);
   71|       |
   72|    139|    va_list args;
   73|    139|    va_start(args, msg);
   74|       |
   75|    139|    char szBuffer[3000];
   76|    139|    const int iLen = vsnprintf(szBuffer, sizeof(szBuffer), msg, args);
   77|    139|    ai_assert(iLen > 0);
   78|       |
   79|    139|    va_end(args);
   80|       |
   81|    139|    throw DeadlyImportError("Validation failed: ", std::string(szBuffer, iLen));
   82|    139|}
_ZN6Assimp17ValidateDSProcess13ReportWarningEPKcz:
   84|  2.15k|void ValidateDSProcess::ReportWarning(const char *msg, ...) {
   85|  2.15k|    ai_assert(nullptr != msg);
   86|       |
   87|  2.15k|    va_list args;
   88|  2.15k|    va_start(args, msg);
   89|       |
   90|  2.15k|    char szBuffer[3000];
   91|  2.15k|    const int iLen = vsnprintf(szBuffer, sizeof(szBuffer), msg, args);
   92|  2.15k|    ai_assert(iLen > 0);
   93|       |
   94|  2.15k|    va_end(args);
   95|       |    ASSIMP_LOG_WARN("Validation warning: ", std::string(szBuffer, iLen));
   96|  2.15k|}
_ZN6Assimp17ValidateDSProcess7ExecuteEP7aiScene:
  183|  1.62k|void ValidateDSProcess::Execute(aiScene *pScene) {
  184|  1.62k|    mScene = pScene;
  185|  1.62k|    ASSIMP_LOG_DEBUG("ValidateDataStructureProcess begin");
  186|       |
  187|       |    // validate the node graph of the scene
  188|  1.62k|    Validate(pScene->mRootNode);
  189|       |
  190|       |    // validate all meshes
  191|  1.62k|    if (pScene->mNumMeshes) {
  ------------------
  |  Branch (191:9): [True: 1.37k, False: 248]
  ------------------
  192|  1.37k|        DoValidation(pScene->mMeshes, pScene->mNumMeshes, "mMeshes", "mNumMeshes");
  193|  1.37k|    } else if (!(mScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE)) {
  ------------------
  |  Branch (193:16): [True: 0, False: 248]
  ------------------
  194|      0|        ReportError("aiScene::mNumMeshes is 0. At least one mesh must be there");
  195|    248|    } else if (pScene->mMeshes) {
  ------------------
  |  Branch (195:16): [True: 0, False: 248]
  ------------------
  196|      0|        ReportError("aiScene::mMeshes is non-null although there are no meshes");
  197|      0|    }
  198|       |
  199|       |    // validate all animations
  200|  1.62k|    if (pScene->mNumAnimations) {
  ------------------
  |  Branch (200:9): [True: 0, False: 1.62k]
  ------------------
  201|      0|        DoValidation(pScene->mAnimations, pScene->mNumAnimations,
  202|      0|                "mAnimations", "mNumAnimations");
  203|  1.62k|    } else if (pScene->mAnimations) {
  ------------------
  |  Branch (203:16): [True: 0, False: 1.62k]
  ------------------
  204|      0|        ReportError("aiScene::mAnimations is non-null although there are no animations");
  205|      0|    }
  206|       |
  207|       |    // validate all cameras
  208|  1.62k|    if (pScene->mNumCameras) {
  ------------------
  |  Branch (208:9): [True: 0, False: 1.62k]
  ------------------
  209|      0|        DoValidationWithNameCheck(pScene->mCameras, pScene->mNumCameras,
  210|      0|                "mCameras", "mNumCameras");
  211|  1.62k|    } else if (pScene->mCameras) {
  ------------------
  |  Branch (211:16): [True: 0, False: 1.62k]
  ------------------
  212|      0|        ReportError("aiScene::mCameras is non-null although there are no cameras");
  213|      0|    }
  214|       |
  215|       |    // validate all lights
  216|  1.62k|    if (pScene->mNumLights) {
  ------------------
  |  Branch (216:9): [True: 0, False: 1.62k]
  ------------------
  217|      0|        DoValidationWithNameCheck(pScene->mLights, pScene->mNumLights,
  218|      0|                "mLights", "mNumLights");
  219|  1.62k|    } else if (pScene->mLights) {
  ------------------
  |  Branch (219:16): [True: 0, False: 1.62k]
  ------------------
  220|      0|        ReportError("aiScene::mLights is non-null although there are no lights");
  221|      0|    }
  222|       |
  223|       |    // validate all textures
  224|  1.62k|    if (pScene->mNumTextures) {
  ------------------
  |  Branch (224:9): [True: 33, False: 1.59k]
  ------------------
  225|     33|        DoValidation(pScene->mTextures, pScene->mNumTextures,
  226|     33|                "mTextures", "mNumTextures");
  227|  1.59k|    } else if (pScene->mTextures) {
  ------------------
  |  Branch (227:16): [True: 0, False: 1.59k]
  ------------------
  228|      0|        ReportError("aiScene::mTextures is non-null although there are no textures");
  229|      0|    }
  230|       |
  231|       |    // validate all materials
  232|  1.62k|    if (pScene->mNumMaterials) {
  ------------------
  |  Branch (232:9): [True: 1.48k, False: 139]
  ------------------
  233|  1.48k|        DoValidation(pScene->mMaterials, pScene->mNumMaterials, "mMaterials", "mNumMaterials");
  234|  1.48k|    }
  235|    139|    else if (pScene->mMaterials) {
  ------------------
  |  Branch (235:14): [True: 0, False: 139]
  ------------------
  236|      0|        ReportError("aiScene::mMaterials is non-null although there are no materials");
  237|      0|    }
  238|       |
  239|       |    //  if (!has)ReportError("The aiScene data structure is empty");
  240|       |    ASSIMP_LOG_DEBUG("ValidateDataStructureProcess end");
  241|  1.62k|}
_ZN6Assimp17ValidateDSProcess8ValidateEPK6aiMesh:
  273|  1.37k|void ValidateDSProcess::Validate(const aiMesh *pMesh) {
  274|       |    // validate the material index of the mesh
  275|  1.37k|    if (mScene->mNumMaterials && pMesh->mMaterialIndex >= mScene->mNumMaterials) {
  ------------------
  |  Branch (275:9): [True: 1.37k, False: 0]
  |  Branch (275:34): [True: 0, False: 1.37k]
  ------------------
  276|      0|        ReportError("aiMesh::mMaterialIndex is invalid (value: %i maximum: %i)",
  277|      0|                pMesh->mMaterialIndex, mScene->mNumMaterials - 1);
  278|      0|    }
  279|       |
  280|  1.37k|    Validate(&pMesh->mName);
  281|       |
  282|  35.6k|    for (unsigned int i = 0; i < pMesh->mNumFaces; ++i) {
  ------------------
  |  Branch (282:30): [True: 34.2k, False: 1.37k]
  ------------------
  283|  34.2k|        aiFace &face = pMesh->mFaces[i];
  284|       |
  285|  34.2k|        if (pMesh->mPrimitiveTypes) {
  ------------------
  |  Branch (285:13): [True: 34.2k, False: 0]
  ------------------
  286|  34.2k|            switch (face.mNumIndices) {
  287|      0|            case 0:
  ------------------
  |  Branch (287:13): [True: 0, False: 34.2k]
  ------------------
  288|      0|                ReportError("aiMesh::mFaces[%i].mNumIndices is 0", i);
  289|  1.02k|            case 1:
  ------------------
  |  Branch (289:13): [True: 1.02k, False: 33.2k]
  ------------------
  290|  1.02k|                if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POINT)) {
  ------------------
  |  Branch (290:21): [True: 0, False: 1.02k]
  ------------------
  291|      0|                    ReportError("aiMesh::mFaces[%i] is a POINT but aiMesh::mPrimitiveTypes "
  292|      0|                                "does not report the POINT flag",
  293|      0|                            i);
  294|      0|                }
  295|  1.02k|                break;
  296|  5.31k|            case 2:
  ------------------
  |  Branch (296:13): [True: 5.31k, False: 28.9k]
  ------------------
  297|  5.31k|                if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_LINE)) {
  ------------------
  |  Branch (297:21): [True: 0, False: 5.31k]
  ------------------
  298|      0|                    ReportError("aiMesh::mFaces[%i] is a LINE but aiMesh::mPrimitiveTypes "
  299|      0|                                "does not report the LINE flag",
  300|      0|                            i);
  301|      0|                }
  302|  5.31k|                break;
  303|  27.9k|            case 3:
  ------------------
  |  Branch (303:13): [True: 27.9k, False: 6.33k]
  ------------------
  304|  27.9k|                if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE)) {
  ------------------
  |  Branch (304:21): [True: 0, False: 27.9k]
  ------------------
  305|      0|                    ReportError("aiMesh::mFaces[%i] is a TRIANGLE but aiMesh::mPrimitiveTypes "
  306|      0|                                "does not report the TRIANGLE flag",
  307|      0|                            i);
  308|      0|                }
  309|  27.9k|                break;
  310|      0|            default:
  ------------------
  |  Branch (310:13): [True: 0, False: 34.2k]
  ------------------
  311|      0|                if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON)) {
  ------------------
  |  Branch (311:21): [True: 0, False: 0]
  ------------------
  312|      0|                    this->ReportError("aiMesh::mFaces[%i] is a POLYGON but aiMesh::mPrimitiveTypes "
  313|      0|                                      "does not report the POLYGON flag",
  314|      0|                            i);
  315|      0|                }
  316|      0|                break;
  317|  34.2k|            };
  318|  34.2k|        }
  319|       |
  320|  34.2k|        if (!face.mIndices)
  ------------------
  |  Branch (320:13): [True: 0, False: 34.2k]
  ------------------
  321|      0|            ReportError("aiMesh::mFaces[%i].mIndices is nullptr", i);
  322|  34.2k|    }
  323|       |
  324|       |    // positions must always be there ...
  325|  1.37k|    if (!pMesh->mNumVertices || (!pMesh->mVertices && !mScene->mFlags)) {
  ------------------
  |  Branch (325:9): [True: 10, False: 1.36k]
  |  Branch (325:34): [True: 0, False: 1.36k]
  |  Branch (325:55): [True: 0, False: 0]
  ------------------
  326|     10|        ReportError("The mesh %s contains no vertices", pMesh->mName.C_Str());
  327|     10|    }
  328|       |
  329|  1.37k|    if (pMesh->mNumVertices > AI_MAX_VERTICES) {
  ------------------
  |  Branch (329:9): [True: 0, False: 1.37k]
  ------------------
  330|      0|        ReportError("Mesh has too many vertices: %u, but the limit is %u", pMesh->mNumVertices, AI_MAX_VERTICES);
  331|      0|    }
  332|  1.37k|    if (pMesh->mNumFaces > AI_MAX_FACES) {
  ------------------
  |  Branch (332:9): [True: 0, False: 1.37k]
  ------------------
  333|      0|        ReportError("Mesh has too many faces: %u, but the limit is %u", pMesh->mNumFaces, AI_MAX_FACES);
  334|      0|    }
  335|       |
  336|       |    // if tangents are there there must also be bitangent vectors ...
  337|  1.37k|    if ((pMesh->mTangents != nullptr) != (pMesh->mBitangents != nullptr)) {
  ------------------
  |  Branch (337:9): [True: 0, False: 1.37k]
  ------------------
  338|      0|        ReportError("If there are tangents, bitangent vectors must be present as well");
  339|      0|    }
  340|       |
  341|       |    // faces, too
  342|  1.37k|    if (!pMesh->mNumFaces || (!pMesh->mFaces && !mScene->mFlags)) {
  ------------------
  |  Branch (342:9): [True: 15, False: 1.36k]
  |  Branch (342:31): [True: 0, False: 1.36k]
  |  Branch (342:49): [True: 0, False: 0]
  ------------------
  343|      5|        ReportError("Mesh %s contains no faces", pMesh->mName.C_Str());
  344|      5|    }
  345|       |
  346|       |    // now check whether the face indexing layout is correct:
  347|       |    // unique vertices, pseudo-indexed.
  348|  1.37k|    std::vector<bool> abRefList;
  349|  1.37k|    abRefList.resize(pMesh->mNumVertices, false);
  350|  35.6k|    for (unsigned int i = 0; i < pMesh->mNumFaces; ++i) {
  ------------------
  |  Branch (350:30): [True: 34.2k, False: 1.37k]
  ------------------
  351|  34.2k|        aiFace &face = pMesh->mFaces[i];
  352|  34.2k|        if (face.mNumIndices > AI_MAX_FACE_INDICES) {
  ------------------
  |  Branch (352:13): [True: 0, False: 34.2k]
  ------------------
  353|      0|            ReportError("Face %u has too many faces: %u, but the limit is %u", i, face.mNumIndices, AI_MAX_FACE_INDICES);
  354|      0|        }
  355|       |
  356|   129k|        for (unsigned int a = 0; a < face.mNumIndices; ++a) {
  ------------------
  |  Branch (356:34): [True: 95.4k, False: 34.2k]
  ------------------
  357|  95.4k|            if (face.mIndices[a] >= pMesh->mNumVertices) {
  ------------------
  |  Branch (357:17): [True: 0, False: 95.4k]
  ------------------
  358|      0|                ReportError("aiMesh::mFaces[%i]::mIndices[%i] is out of range", i, a);
  359|      0|            }
  360|  95.4k|            abRefList[face.mIndices[a]] = true;
  361|  95.4k|        }
  362|  34.2k|    }
  363|       |
  364|       |    // check whether there are vertices that aren't referenced by a face
  365|  1.37k|    bool b = false;
  366|  37.7k|    for (unsigned int i = 0; i < pMesh->mNumVertices; ++i) {
  ------------------
  |  Branch (366:30): [True: 36.3k, False: 1.37k]
  ------------------
  367|  36.3k|        if (!abRefList[i]) b = true;
  ------------------
  |  Branch (367:13): [True: 577, False: 35.7k]
  ------------------
  368|  36.3k|    }
  369|  1.37k|    abRefList.clear();
  370|  1.37k|    if (b) {
  ------------------
  |  Branch (370:9): [True: 268, False: 1.10k]
  ------------------
  371|    268|        ReportWarning("There are unreferenced vertices");
  372|    268|    }
  373|       |
  374|       |    // vertex color channel 2 may not be set if channel 1 is zero ...
  375|  1.37k|    {
  376|  1.37k|        unsigned int i = 0;
  377|  1.58k|        for (; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
  ------------------
  |  Branch (377:16): [True: 1.57k, False: 15]
  ------------------
  378|  1.57k|            if (!pMesh->HasVertexColors(i)) break;
  ------------------
  |  Branch (378:17): [True: 1.36k, False: 213]
  ------------------
  379|  1.57k|        }
  380|  12.0k|        for (; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i)
  ------------------
  |  Branch (380:16): [True: 10.6k, False: 1.37k]
  ------------------
  381|  10.6k|            if (pMesh->HasVertexColors(i)) {
  ------------------
  |  Branch (381:17): [True: 0, False: 10.6k]
  ------------------
  382|      0|                ReportError("Vertex color channel %i is exists "
  383|      0|                            "although the previous channel was nullptr.",
  384|      0|                        i);
  385|      0|            }
  386|  1.37k|    }
  387|       |
  388|       |    // now validate all bones
  389|  1.37k|    if (pMesh->mNumBones) {
  ------------------
  |  Branch (389:9): [True: 196, False: 1.18k]
  ------------------
  390|    196|        if (!pMesh->mBones) {
  ------------------
  |  Branch (390:13): [True: 0, False: 196]
  ------------------
  391|      0|            ReportError("aiMesh::mBones is nullptr (aiMesh::mNumBones is %i)",
  392|      0|                    pMesh->mNumBones);
  393|      0|        }
  394|    196|        std::unique_ptr<float[]> afSum(nullptr);
  395|    196|        if (pMesh->mNumVertices) {
  ------------------
  |  Branch (395:13): [True: 196, False: 0]
  ------------------
  396|    196|            afSum.reset(new float[pMesh->mNumVertices]);
  397|    873|            for (unsigned int i = 0; i < pMesh->mNumVertices; ++i)
  ------------------
  |  Branch (397:38): [True: 677, False: 196]
  ------------------
  398|    677|                afSum[i] = 0.0f;
  399|    196|        }
  400|       |
  401|       |        // check whether there are duplicate bone names
  402|  1.94k|        for (unsigned int i = 0; i < pMesh->mNumBones; ++i) {
  ------------------
  |  Branch (402:34): [True: 1.74k, False: 196]
  ------------------
  403|  1.74k|            const aiBone *bone = pMesh->mBones[i];
  404|  1.74k|            if (bone->mNumWeights > AI_MAX_BONE_WEIGHTS) {
  ------------------
  |  Branch (404:17): [True: 0, False: 1.74k]
  ------------------
  405|      0|                ReportError("Bone %u has too many weights: %u, but the limit is %u", i, bone->mNumWeights, AI_MAX_BONE_WEIGHTS);
  406|      0|            }
  407|       |
  408|  1.74k|            if (!pMesh->mBones[i]) {
  ------------------
  |  Branch (408:17): [True: 0, False: 1.74k]
  ------------------
  409|      0|                ReportError("aiMesh::mBones[%i] is nullptr (aiMesh::mNumBones is %i)",
  410|      0|                        i, pMesh->mNumBones);
  411|      0|            }
  412|  1.74k|            Validate(pMesh, pMesh->mBones[i], afSum.get());
  413|       |
  414|  9.64k|            for (unsigned int a = i + 1; a < pMesh->mNumBones; ++a) {
  ------------------
  |  Branch (414:42): [True: 7.90k, False: 1.74k]
  ------------------
  415|  7.90k|                if (pMesh->mBones[i]->mName == pMesh->mBones[a]->mName) {
  ------------------
  |  Branch (415:21): [True: 25, False: 7.87k]
  ------------------
  416|     25|                    const char *name = "unknown";
  417|     25|                    if (nullptr != pMesh->mBones[i]->mName.C_Str()) {
  ------------------
  |  Branch (417:25): [True: 25, False: 0]
  ------------------
  418|     25|                        name = pMesh->mBones[i]->mName.C_Str();
  419|     25|                    }
  420|     25|                    ReportError("aiMesh::mBones[%i], name = \"%s\" has the same name as "
  421|     25|                                "aiMesh::mBones[%i]",
  422|     25|                            i, name, a);
  423|     25|                }
  424|  7.90k|            }
  425|  1.74k|        }
  426|       |        // check whether all bone weights for a vertex sum to 1.0 ...
  427|    772|        for (unsigned int i = 0; i < pMesh->mNumVertices; ++i) {
  ------------------
  |  Branch (427:34): [True: 576, False: 196]
  ------------------
  428|    576|            if (afSum[i] && (afSum[i] <= 0.94 || afSum[i] >= 1.05)) {
  ------------------
  |  Branch (428:17): [True: 492, False: 84]
  |  Branch (428:30): [True: 150, False: 342]
  |  Branch (428:50): [True: 288, False: 54]
  ------------------
  429|    438|                ReportWarning("aiMesh::mVertices[%i]: bone weight sum != 1.0 (sum is %f)", i, afSum[i]);
  430|    438|            }
  431|    576|        }
  432|  1.18k|    } else if (pMesh->mBones) {
  ------------------
  |  Branch (432:16): [True: 3, False: 1.17k]
  ------------------
  433|      3|        ReportError("aiMesh::mBones is non-null although there are no bones");
  434|      3|    }
  435|  1.37k|}
_ZN6Assimp17ValidateDSProcess8ValidateEPK6aiMeshPK6aiBonePf:
  438|  1.74k|void ValidateDSProcess::Validate(const aiMesh *pMesh, const aiBone *pBone, float *afSum) {
  439|  1.74k|    this->Validate(&pBone->mName);
  440|       |
  441|  1.74k|    if (!pBone->mNumWeights) {
  ------------------
  |  Branch (441:9): [True: 0, False: 1.74k]
  ------------------
  442|      0|        ReportWarning("aiBone::mNumWeights is zero");
  443|      0|    }
  444|       |
  445|       |    // check whether all vertices affected by this bone are valid
  446|  5.56k|    for (unsigned int i = 0; i < pBone->mNumWeights; ++i) {
  ------------------
  |  Branch (446:30): [True: 3.81k, False: 1.74k]
  ------------------
  447|  3.81k|        if (pBone->mWeights[i].mVertexId >= pMesh->mNumVertices) {
  ------------------
  |  Branch (447:13): [True: 3, False: 3.81k]
  ------------------
  448|      3|            ReportError("aiBone::mWeights[%i].mVertexId is out of range", i);
  449|  3.81k|        } else if (!pBone->mWeights[i].mWeight || pBone->mWeights[i].mWeight > 1.0f) {
  ------------------
  |  Branch (449:20): [True: 798, False: 3.01k]
  |  Branch (449:51): [True: 625, False: 2.39k]
  ------------------
  450|  1.42k|                ReportWarning("aiBone::mWeights[%i].mWeight has an invalid value %i. Value must be greater than zero and less than 1.", i, pBone->mWeights[i].mWeight);
  451|  1.42k|        }
  452|  3.81k|        afSum[pBone->mWeights[i].mVertexId] += pBone->mWeights[i].mWeight;
  453|  3.81k|    }
  454|  1.74k|}
_ZN6Assimp17ValidateDSProcess24SearchForInvalidTexturesEPK10aiMaterial13aiTextureType:
  491|  43.3k|        aiTextureType type) {
  492|  43.3k|    const char *szType = aiTextureTypeToString(type);
  493|       |
  494|       |    // ****************************************************************************
  495|       |    // Search all keys of the material ...
  496|       |    // textures must be specified with ascending indices
  497|       |    // (e.g. diffuse #2 may not be specified if diffuse #1 is not there ...)
  498|       |    // ****************************************************************************
  499|       |
  500|  43.3k|    int iNumIndices = 0;
  501|  43.3k|    int iIndex = -1;
  502|   544k|    for (unsigned int i = 0; i < pMaterial->mNumProperties; ++i) {
  ------------------
  |  Branch (502:30): [True: 501k, False: 43.3k]
  ------------------
  503|   501k|        aiMaterialProperty *prop = pMaterial->mProperties[i];
  504|   501k|        ai_assert(nullptr != prop);
  505|   501k|        if (!::strcmp(prop->mKey.data, "$tex.file") && prop->mSemantic == static_cast<unsigned int>(type)) {
  ------------------
  |  Branch (505:13): [True: 1.02k, False: 500k]
  |  Branch (505:56): [True: 60, False: 960]
  ------------------
  506|     60|            iIndex = std::max(iIndex, (int)prop->mIndex);
  507|     60|            ++iNumIndices;
  508|       |
  509|     60|            if (aiPTI_String != prop->mType) {
  ------------------
  |  Branch (509:17): [True: 0, False: 60]
  ------------------
  510|      0|                ReportError("Material property %s is expected to be a string", prop->mKey.data);
  511|      0|            }
  512|     60|        }
  513|   501k|    }
  514|  43.3k|    if (iIndex + 1 != iNumIndices) {
  ------------------
  |  Branch (514:9): [True: 0, False: 43.3k]
  ------------------
  515|      0|        ReportError("%s #%i is set, but there are only %i %s textures",
  516|      0|                szType, iIndex, iNumIndices, szType);
  517|      0|    }
  518|  43.3k|    if (!iNumIndices) {
  ------------------
  |  Branch (518:9): [True: 43.3k, False: 60]
  ------------------
  519|  43.3k|        return;
  520|  43.3k|    }
  521|     60|    std::vector<aiTextureMapping> mappings(iNumIndices);
  522|       |
  523|       |    // Now check whether all UV indices are valid ...
  524|     60|    bool bNoSpecified = true;
  525|  1.58k|    for (unsigned int i = 0; i < pMaterial->mNumProperties; ++i) {
  ------------------
  |  Branch (525:30): [True: 1.52k, False: 60]
  ------------------
  526|  1.52k|        aiMaterialProperty *prop = pMaterial->mProperties[i];
  527|  1.52k|        if (static_cast<aiTextureType>(prop->mSemantic) != type) {
  ------------------
  |  Branch (527:13): [True: 1.12k, False: 406]
  ------------------
  528|  1.12k|            continue;
  529|  1.12k|        }
  530|       |
  531|    406|        if ((int)prop->mIndex >= iNumIndices) {
  ------------------
  |  Branch (531:13): [True: 0, False: 406]
  ------------------
  532|      0|            ReportError("Found texture property with index %i, although there "
  533|      0|                        "are only %i textures of type %s",
  534|      0|                    prop->mIndex, iNumIndices, szType);
  535|      0|        }
  536|       |
  537|    406|        if (!::strcmp(prop->mKey.data, "$tex.mapping")) {
  ------------------
  |  Branch (537:13): [True: 0, False: 406]
  ------------------
  538|      0|            if (aiPTI_Integer != prop->mType || prop->mDataLength < sizeof(aiTextureMapping)) {
  ------------------
  |  Branch (538:17): [True: 0, False: 0]
  |  Branch (538:49): [True: 0, False: 0]
  ------------------
  539|      0|                ReportError("Material property %s%i is expected to be an integer (size is %i)",
  540|      0|                        prop->mKey.data, prop->mIndex, prop->mDataLength);
  541|      0|            }
  542|      0|            mappings[prop->mIndex] = *((aiTextureMapping *)prop->mData);
  543|    406|        } else if (!::strcmp(prop->mKey.data, "$tex.uvtrafo")) {
  ------------------
  |  Branch (543:20): [True: 0, False: 406]
  ------------------
  544|      0|            if (aiPTI_Float != prop->mType || prop->mDataLength < sizeof(aiUVTransform)) {
  ------------------
  |  Branch (544:17): [True: 0, False: 0]
  |  Branch (544:47): [True: 0, False: 0]
  ------------------
  545|      0|                ReportError("Material property %s%i is expected to be 5 floats large (size is %i)",
  546|      0|                        prop->mKey.data, prop->mIndex, prop->mDataLength);
  547|      0|            }
  548|       |            //mappings[prop->mIndex] = ((aiUVTransform*)prop->mData);
  549|    406|        } else if (!::strcmp(prop->mKey.data, "$tex.uvwsrc")) {
  ------------------
  |  Branch (549:20): [True: 60, False: 346]
  ------------------
  550|     60|            if (aiPTI_Integer != prop->mType || sizeof(int) > prop->mDataLength) {
  ------------------
  |  Branch (550:17): [True: 0, False: 60]
  |  Branch (550:49): [True: 0, False: 60]
  ------------------
  551|      0|                ReportError("Material property %s%i is expected to be an integer (size is %i)",
  552|      0|                        prop->mKey.data, prop->mIndex, prop->mDataLength);
  553|      0|            }
  554|     60|            bNoSpecified = false;
  555|       |
  556|       |            // Ignore UV indices for texture channels that are not there ...
  557|       |
  558|       |            // Get the value
  559|     60|            iIndex = *((unsigned int *)prop->mData);
  560|       |
  561|       |            // Check whether there is a mesh using this material
  562|       |            // which has not enough UV channels ...
  563|    120|            for (unsigned int a = 0; a < mScene->mNumMeshes; ++a) {
  ------------------
  |  Branch (563:38): [True: 60, False: 60]
  ------------------
  564|     60|                aiMesh *mesh = this->mScene->mMeshes[a];
  565|     60|                if (mesh->mMaterialIndex == (unsigned int)i) {
  ------------------
  |  Branch (565:21): [True: 0, False: 60]
  ------------------
  566|      0|                    int iChannels = 0;
  567|      0|                    while (mesh->HasTextureCoords(iChannels))
  ------------------
  |  Branch (567:28): [True: 0, False: 0]
  ------------------
  568|      0|                        ++iChannels;
  569|      0|                    if (iIndex >= iChannels) {
  ------------------
  |  Branch (569:25): [True: 0, False: 0]
  ------------------
  570|      0|                        ReportWarning("Invalid UV index: %i (key %s). Mesh %i has only %i UV channels",
  571|      0|                                iIndex, prop->mKey.data, a, iChannels);
  572|      0|                    }
  573|      0|                }
  574|     60|            }
  575|     60|        }
  576|    406|    }
  577|     60|    if (bNoSpecified) {
  ------------------
  |  Branch (577:9): [True: 0, False: 60]
  ------------------
  578|       |        // Assume that all textures are using the first UV channel
  579|      0|        for (unsigned int a = 0; a < mScene->mNumMeshes; ++a) {
  ------------------
  |  Branch (579:34): [True: 0, False: 0]
  ------------------
  580|      0|            aiMesh *mesh = mScene->mMeshes[a];
  581|      0|            if (mesh->mMaterialIndex == (unsigned int)iIndex && mappings[0] == aiTextureMapping_UV) {
  ------------------
  |  Branch (581:17): [True: 0, False: 0]
  |  Branch (581:65): [True: 0, False: 0]
  ------------------
  582|      0|                if (!mesh->mTextureCoords[0]) {
  ------------------
  |  Branch (582:21): [True: 0, False: 0]
  ------------------
  583|       |                    // This is a special case ... it could be that the
  584|       |                    // original mesh format intended the use of a special
  585|       |                    // mapping here.
  586|      0|                    ReportWarning("UV-mapped texture, but there are no UV coords");
  587|      0|                }
  588|      0|            }
  589|      0|        }
  590|      0|    }
  591|     60|}
_ZN6Assimp17ValidateDSProcess8ValidateEPK10aiMaterial:
  593|  2.55k|void ValidateDSProcess::Validate(const aiMaterial *pMaterial) {
  594|       |    // check whether there are material keys that are obviously not legal
  595|  32.0k|    for (unsigned int i = 0; i < pMaterial->mNumProperties; ++i) {
  ------------------
  |  Branch (595:30): [True: 29.4k, False: 2.55k]
  ------------------
  596|  29.4k|        const aiMaterialProperty *prop = pMaterial->mProperties[i];
  597|  29.4k|        if (!prop) {
  ------------------
  |  Branch (597:13): [True: 0, False: 29.4k]
  ------------------
  598|      0|            ReportError("aiMaterial::mProperties[%i] is nullptr (aiMaterial::mNumProperties is %i)",
  599|      0|                    i, pMaterial->mNumProperties);
  600|      0|        }
  601|  29.4k|        if (!prop->mDataLength || !prop->mData) {
  ------------------
  |  Branch (601:13): [True: 0, False: 29.4k]
  |  Branch (601:35): [True: 0, False: 29.4k]
  ------------------
  602|      0|            ReportError("aiMaterial::mProperties[%i].mDataLength or "
  603|      0|                        "aiMaterial::mProperties[%i].mData is 0",
  604|      0|                    i, i);
  605|      0|        }
  606|       |        // check all predefined types
  607|  29.4k|        if (aiPTI_String == prop->mType) {
  ------------------
  |  Branch (607:13): [True: 3.75k, False: 25.7k]
  ------------------
  608|       |            // FIX: strings are now stored in a less expensive way, but we can't use the
  609|       |            // validation routine for 'normal' aiStrings
  610|  3.75k|            if (prop->mDataLength < 5 || prop->mDataLength < 4 + (*reinterpret_cast<uint32_t *>(prop->mData)) + 1) {
  ------------------
  |  Branch (610:17): [True: 0, False: 3.75k]
  |  Branch (610:42): [True: 0, False: 3.75k]
  ------------------
  611|      0|                ReportError("aiMaterial::mProperties[%i].mDataLength is "
  612|      0|                            "too small to contain a string (%i, needed: %i)",
  613|      0|                        i, prop->mDataLength, static_cast<int>(sizeof(aiString)));
  614|      0|            }
  615|  3.75k|            if (prop->mData[prop->mDataLength - 1]) {
  ------------------
  |  Branch (615:17): [True: 0, False: 3.75k]
  ------------------
  616|      0|                ReportError("Missing null-terminator in string material property");
  617|      0|            }
  618|       |            //  Validate((const aiString*)prop->mData);
  619|  25.7k|        } else if (aiPTI_Float == prop->mType) {
  ------------------
  |  Branch (619:20): [True: 20.4k, False: 5.33k]
  ------------------
  620|  20.4k|            if (prop->mDataLength < sizeof(float)) {
  ------------------
  |  Branch (620:17): [True: 0, False: 20.4k]
  ------------------
  621|      0|                ReportError("aiMaterial::mProperties[%i].mDataLength is "
  622|      0|                            "too small to contain a float (%i, needed: %i)",
  623|      0|                        i, prop->mDataLength, static_cast<int>(sizeof(float)));
  624|      0|            }
  625|  20.4k|        } else if (aiPTI_Integer == prop->mType) {
  ------------------
  |  Branch (625:20): [True: 60, False: 5.27k]
  ------------------
  626|     60|            if (prop->mDataLength < sizeof(int)) {
  ------------------
  |  Branch (626:17): [True: 0, False: 60]
  ------------------
  627|      0|                ReportError("aiMaterial::mProperties[%i].mDataLength is "
  628|      0|                            "too small to contain an integer (%i, needed: %i)",
  629|      0|                        i, prop->mDataLength, static_cast<int>(sizeof(int)));
  630|      0|            }
  631|     60|        }
  632|       |        // TODO: check whether there is a key with an unknown name ...
  633|  29.4k|    }
  634|       |
  635|       |    // make some more specific tests
  636|  2.55k|    ai_real fTemp;
  637|  2.55k|    int iShading;
  638|  2.55k|    if (AI_SUCCESS == aiGetMaterialInteger(pMaterial, AI_MATKEY_SHADING_MODEL, &iShading)) {
  ------------------
  |  Branch (638:9): [True: 2.55k, False: 0]
  ------------------
  639|  2.55k|        switch ((aiShadingMode)iShading) {
  640|      0|        case aiShadingMode_Blinn:
  ------------------
  |  Branch (640:9): [True: 0, False: 2.55k]
  ------------------
  641|      0|        case aiShadingMode_CookTorrance:
  ------------------
  |  Branch (641:9): [True: 0, False: 2.55k]
  ------------------
  642|      0|        case aiShadingMode_Phong:
  ------------------
  |  Branch (642:9): [True: 0, False: 2.55k]
  ------------------
  643|       |
  644|      0|            if (AI_SUCCESS != aiGetMaterialFloat(pMaterial, AI_MATKEY_SHININESS, &fTemp)) {
  ------------------
  |  Branch (644:17): [True: 0, False: 0]
  ------------------
  645|      0|                ReportWarning("A specular shading model is specified but there is no "
  646|      0|                              "AI_MATKEY_SHININESS key");
  647|      0|            }
  648|      0|            if (AI_SUCCESS == aiGetMaterialFloat(pMaterial, AI_MATKEY_SHININESS_STRENGTH, &fTemp) && !fTemp) {
  ------------------
  |  Branch (648:17): [True: 0, False: 0]
  |  Branch (648:102): [True: 0, False: 0]
  ------------------
  649|      0|                ReportWarning("A specular shading model is specified but the value of the "
  650|      0|                              "AI_MATKEY_SHININESS_STRENGTH key is 0.0");
  651|      0|            }
  652|      0|            break;
  653|  2.55k|        default:
  ------------------
  |  Branch (653:9): [True: 2.55k, False: 0]
  ------------------
  654|  2.55k|            break;
  655|  2.55k|        }
  656|  2.55k|    }
  657|       |
  658|  2.55k|    if (AI_SUCCESS == aiGetMaterialFloat(pMaterial, AI_MATKEY_OPACITY, &fTemp) && (!fTemp || fTemp > 1.01)) {
  ------------------
  |  Branch (658:9): [True: 2.55k, False: 0]
  |  Branch (658:84): [True: 13, False: 2.53k]
  |  Branch (658:94): [True: 7, False: 2.53k]
  ------------------
  659|     20|        ReportWarning("Invalid opacity value (must be 0 < opacity < 1.0)");
  660|     20|    }
  661|       |
  662|       |    // Check whether there are invalid texture keys
  663|       |    // TODO: that's a relict of the past, where texture type and index were baked
  664|       |    // into the material string ... we could do that in one single pass.
  665|  2.55k|    SearchForInvalidTextures(pMaterial, aiTextureType_DIFFUSE);
  666|  2.55k|    SearchForInvalidTextures(pMaterial, aiTextureType_SPECULAR);
  667|  2.55k|    SearchForInvalidTextures(pMaterial, aiTextureType_AMBIENT);
  668|  2.55k|    SearchForInvalidTextures(pMaterial, aiTextureType_EMISSIVE);
  669|  2.55k|    SearchForInvalidTextures(pMaterial, aiTextureType_OPACITY);
  670|  2.55k|    SearchForInvalidTextures(pMaterial, aiTextureType_SHININESS);
  671|  2.55k|    SearchForInvalidTextures(pMaterial, aiTextureType_HEIGHT);
  672|  2.55k|    SearchForInvalidTextures(pMaterial, aiTextureType_NORMALS);
  673|  2.55k|    SearchForInvalidTextures(pMaterial, aiTextureType_DISPLACEMENT);
  674|  2.55k|    SearchForInvalidTextures(pMaterial, aiTextureType_LIGHTMAP);
  675|  2.55k|    SearchForInvalidTextures(pMaterial, aiTextureType_REFLECTION);
  676|  2.55k|    SearchForInvalidTextures(pMaterial, aiTextureType_BASE_COLOR);
  677|  2.55k|    SearchForInvalidTextures(pMaterial, aiTextureType_NORMAL_CAMERA);
  678|  2.55k|    SearchForInvalidTextures(pMaterial, aiTextureType_EMISSION_COLOR);
  679|  2.55k|    SearchForInvalidTextures(pMaterial, aiTextureType_METALNESS);
  680|  2.55k|    SearchForInvalidTextures(pMaterial, aiTextureType_DIFFUSE_ROUGHNESS);
  681|  2.55k|    SearchForInvalidTextures(pMaterial, aiTextureType_AMBIENT_OCCLUSION);
  682|  2.55k|}
_ZN6Assimp17ValidateDSProcess8ValidateEPK9aiTexture:
  685|     33|void ValidateDSProcess::Validate(const aiTexture *pTexture) {
  686|       |    // the data section may NEVER be nullptr
  687|     33|    if (nullptr == pTexture->pcData) {
  ------------------
  |  Branch (687:9): [True: 0, False: 33]
  ------------------
  688|      0|        ReportError("aiTexture::pcData is nullptr");
  689|      0|    }
  690|     33|    if (pTexture->mHeight) {
  ------------------
  |  Branch (690:9): [True: 0, False: 33]
  ------------------
  691|      0|        if (!pTexture->mWidth) {
  ------------------
  |  Branch (691:13): [True: 0, False: 0]
  ------------------
  692|      0|            ReportError("aiTexture::mWidth is zero (aiTexture::mHeight is %i, uncompressed texture)",
  693|      0|                    pTexture->mHeight);
  694|      0|        }
  695|     33|    } else {
  696|     33|        if (!pTexture->mWidth) {
  ------------------
  |  Branch (696:13): [True: 0, False: 33]
  ------------------
  697|      0|            ReportError("aiTexture::mWidth is zero (compressed texture)");
  698|      0|        }
  699|     33|        if ('\0' != pTexture->achFormatHint[HINTMAXTEXTURELEN - 1]) {
  ------------------
  |  Branch (699:13): [True: 0, False: 33]
  ------------------
  700|      0|            ReportWarning("aiTexture::achFormatHint must be zero-terminated");
  701|     33|        } else if ('.' == pTexture->achFormatHint[0]) {
  ------------------
  |  Branch (701:20): [True: 1, False: 32]
  ------------------
  702|      1|            ReportWarning("aiTexture::achFormatHint should contain a file extension "
  703|      1|                          "without a leading dot (format hint: %s).",
  704|      1|                    pTexture->achFormatHint);
  705|      1|        }
  706|     33|    }
  707|       |
  708|     33|    const char *sz = pTexture->achFormatHint;
  709|     33|    if ((sz[0] >= 'A' && sz[0] <= 'Z') ||
  ------------------
  |  Branch (709:10): [True: 30, False: 3]
  |  Branch (709:26): [True: 2, False: 28]
  ------------------
  710|     31|            (sz[1] >= 'A' && sz[1] <= 'Z') ||
  ------------------
  |  Branch (710:14): [True: 27, False: 4]
  |  Branch (710:30): [True: 1, False: 26]
  ------------------
  711|     30|            (sz[2] >= 'A' && sz[2] <= 'Z') ||
  ------------------
  |  Branch (711:14): [True: 29, False: 1]
  |  Branch (711:30): [True: 1, False: 28]
  ------------------
  712|     29|            (sz[3] >= 'A' && sz[3] <= 'Z')) {
  ------------------
  |  Branch (712:14): [True: 0, False: 29]
  |  Branch (712:30): [True: 0, False: 0]
  ------------------
  713|      4|        ReportError("aiTexture::achFormatHint contains non-lowercase letters");
  714|      4|    }
  715|     33|}
_ZN6Assimp17ValidateDSProcess8ValidateEPK6aiNode:
  850|  7.91k|void ValidateDSProcess::Validate(const aiNode *pNode) {
  851|  7.91k|    if (!pNode) {
  ------------------
  |  Branch (851:9): [True: 89, False: 7.82k]
  ------------------
  852|     89|        ReportError("A node of the scene-graph is nullptr");
  853|     89|    }
  854|       |    // Validate node name string first so that it's safe to use in below expressions
  855|  7.91k|    this->Validate(&pNode->mName);
  856|  7.91k|    const char *nodeName = (&pNode->mName)->C_Str();
  857|  7.91k|    if (pNode != mScene->mRootNode && !pNode->mParent) {
  ------------------
  |  Branch (857:9): [True: 6.28k, False: 1.62k]
  |  Branch (857:39): [True: 0, False: 6.28k]
  ------------------
  858|      0|        ReportError("Non-root node %s lacks a valid parent (aiNode::mParent is nullptr) ", nodeName);
  859|      0|    }
  860|       |
  861|       |    // validate all meshes
  862|  7.91k|    if (pNode->mNumMeshes) {
  ------------------
  |  Branch (862:9): [True: 1.47k, False: 6.44k]
  ------------------
  863|  1.47k|        if (!pNode->mMeshes) {
  ------------------
  |  Branch (863:13): [True: 0, False: 1.47k]
  ------------------
  864|      0|            ReportError("aiNode::mMeshes is nullptr for node %s (aiNode::mNumMeshes is %i)",
  865|      0|                    nodeName, pNode->mNumMeshes);
  866|      0|        }
  867|  1.47k|        std::vector<bool> abHadMesh;
  868|  1.47k|        abHadMesh.resize(mScene->mNumMeshes, false);
  869|  2.94k|        for (unsigned int i = 0; i < pNode->mNumMeshes; ++i) {
  ------------------
  |  Branch (869:34): [True: 1.47k, False: 1.47k]
  ------------------
  870|  1.47k|            if (pNode->mMeshes[i] >= mScene->mNumMeshes) {
  ------------------
  |  Branch (870:17): [True: 0, False: 1.47k]
  ------------------
  871|      0|                ReportError("aiNode::mMeshes[%i] is out of range for node %s (maximum is %i)",
  872|      0|                        pNode->mMeshes[i], nodeName, mScene->mNumMeshes - 1);
  873|      0|            }
  874|  1.47k|            if (abHadMesh[pNode->mMeshes[i]]) {
  ------------------
  |  Branch (874:17): [True: 0, False: 1.47k]
  ------------------
  875|      0|                ReportError("aiNode::mMeshes[%i] is already referenced by this node %s (value: %i)",
  876|      0|                        i, nodeName, pNode->mMeshes[i]);
  877|      0|            }
  878|  1.47k|            abHadMesh[pNode->mMeshes[i]] = true;
  879|  1.47k|        }
  880|  1.47k|    }
  881|  7.91k|    if (pNode->mNumChildren) {
  ------------------
  |  Branch (881:9): [True: 3.53k, False: 4.38k]
  ------------------
  882|  3.53k|        if (!pNode->mChildren) {
  ------------------
  |  Branch (882:13): [True: 0, False: 3.53k]
  ------------------
  883|      0|            ReportError("aiNode::mChildren is nullptr for node %s (aiNode::mNumChildren is %i)",
  884|      0|                    nodeName, pNode->mNumChildren);
  885|      0|        }
  886|  9.82k|        for (unsigned int i = 0; i < pNode->mNumChildren; ++i) {
  ------------------
  |  Branch (886:34): [True: 6.28k, False: 3.53k]
  ------------------
  887|  6.28k|            const aiNode *pChild = pNode->mChildren[i];
  888|  6.28k|            Validate(pChild);
  889|  6.28k|            if (pChild->mParent != pNode) {
  ------------------
  |  Branch (889:17): [True: 0, False: 6.28k]
  ------------------
  890|      0|                const char *parentName = (pChild->mParent != nullptr) ? pChild->mParent->mName.C_Str() : "null";
  ------------------
  |  Branch (890:42): [True: 0, False: 0]
  ------------------
  891|      0|                ReportError("aiNode \"%s\" child %i \"%s\" parent is someone else: \"%s\"", pNode->mName.C_Str(), i, pChild->mName.C_Str(), parentName);
  892|      0|            }
  893|  6.28k|        }
  894|  4.38k|    } else if (pNode->mChildren) {
  ------------------
  |  Branch (894:16): [True: 0, False: 4.38k]
  ------------------
  895|      0|        ReportError("aiNode::mChildren is not nullptr for empty node %s (aiNode::mNumChildren is %i)",
  896|      0|                nodeName, pNode->mNumChildren);
  897|      0|    }
  898|  7.91k|}
_ZN6Assimp17ValidateDSProcess8ValidateEPK8aiString:
  901|  10.9k|void ValidateDSProcess::Validate(const aiString *pString) {
  902|  10.9k|    if (pString->length > AI_MAXLEN) {
  ------------------
  |  Branch (902:9): [True: 0, False: 10.9k]
  ------------------
  903|      0|        ReportError("aiString::length is too large (%u, maximum is %lu)",
  904|      0|                pString->length, AI_MAXLEN);
  905|      0|    }
  906|  10.9k|    const char *sz = pString->data;
  907|   118k|    while (true) {
  ------------------
  |  Branch (907:12): [True: 118k, Folded]
  ------------------
  908|   118k|        if ('\0' == *sz) {
  ------------------
  |  Branch (908:13): [True: 10.9k, False: 107k]
  ------------------
  909|  10.9k|            if (pString->length != (unsigned int)(sz - pString->data)) {
  ------------------
  |  Branch (909:17): [True: 0, False: 10.9k]
  ------------------
  910|      0|                ReportError("aiString::data is invalid: the terminal zero is at a wrong offset");
  911|      0|            }
  912|  10.9k|            break;
  913|   107k|        } else if (sz >= &pString->data[AI_MAXLEN]) {
  ------------------
  |  Branch (913:20): [True: 0, False: 107k]
  ------------------
  914|      0|            ReportError("aiString::data is invalid. There is no terminal character");
  915|      0|        }
  916|   107k|        ++sz;
  917|   107k|    }
  918|  10.9k|}
_ZN6Assimp17ValidateDSProcess12DoValidationI6aiMeshEEvPPT_jPKcS7_:
  109|  1.37k|inline void ValidateDSProcess::DoValidation(T **parray, unsigned int size, const char *firstName, const char *secondName) {
  110|       |    // validate all entries
  111|  1.37k|    if (size == 0) {
  ------------------
  |  Branch (111:9): [True: 0, False: 1.37k]
  ------------------
  112|      0|        return;
  113|      0|    }
  114|       |
  115|  1.37k|    if (!parray) {
  ------------------
  |  Branch (115:9): [True: 0, False: 1.37k]
  ------------------
  116|      0|        ReportError("aiScene::%s is nullptr (aiScene::%s is %i)",
  117|      0|                firstName, secondName, size);
  118|      0|    }
  119|       |
  120|  2.75k|    for (unsigned int i = 0; i < size; ++i) {
  ------------------
  |  Branch (120:30): [True: 1.37k, False: 1.37k]
  ------------------
  121|  1.37k|        if (!parray[i]) {
  ------------------
  |  Branch (121:13): [True: 0, False: 1.37k]
  ------------------
  122|      0|            ReportError("aiScene::%s[%i] is nullptr (aiScene::%s is %i)",
  123|      0|                    firstName, i, secondName, size);
  124|      0|        }
  125|  1.37k|        Validate(parray[i]);
  126|  1.37k|    }
  127|  1.37k|}
_ZN6Assimp17ValidateDSProcess12DoValidationI9aiTextureEEvPPT_jPKcS7_:
  109|     33|inline void ValidateDSProcess::DoValidation(T **parray, unsigned int size, const char *firstName, const char *secondName) {
  110|       |    // validate all entries
  111|     33|    if (size == 0) {
  ------------------
  |  Branch (111:9): [True: 0, False: 33]
  ------------------
  112|      0|        return;
  113|      0|    }
  114|       |
  115|     33|    if (!parray) {
  ------------------
  |  Branch (115:9): [True: 0, False: 33]
  ------------------
  116|      0|        ReportError("aiScene::%s is nullptr (aiScene::%s is %i)",
  117|      0|                firstName, secondName, size);
  118|      0|    }
  119|       |
  120|     66|    for (unsigned int i = 0; i < size; ++i) {
  ------------------
  |  Branch (120:30): [True: 33, False: 33]
  ------------------
  121|     33|        if (!parray[i]) {
  ------------------
  |  Branch (121:13): [True: 0, False: 33]
  ------------------
  122|      0|            ReportError("aiScene::%s[%i] is nullptr (aiScene::%s is %i)",
  123|      0|                    firstName, i, secondName, size);
  124|      0|        }
  125|     33|        Validate(parray[i]);
  126|     33|    }
  127|     33|}
_ZN6Assimp17ValidateDSProcess12DoValidationI10aiMaterialEEvPPT_jPKcS7_:
  109|  1.48k|inline void ValidateDSProcess::DoValidation(T **parray, unsigned int size, const char *firstName, const char *secondName) {
  110|       |    // validate all entries
  111|  1.48k|    if (size == 0) {
  ------------------
  |  Branch (111:9): [True: 0, False: 1.48k]
  ------------------
  112|      0|        return;
  113|      0|    }
  114|       |
  115|  1.48k|    if (!parray) {
  ------------------
  |  Branch (115:9): [True: 0, False: 1.48k]
  ------------------
  116|      0|        ReportError("aiScene::%s is nullptr (aiScene::%s is %i)",
  117|      0|                firstName, secondName, size);
  118|      0|    }
  119|       |
  120|  4.03k|    for (unsigned int i = 0; i < size; ++i) {
  ------------------
  |  Branch (120:30): [True: 2.55k, False: 1.48k]
  ------------------
  121|  2.55k|        if (!parray[i]) {
  ------------------
  |  Branch (121:13): [True: 0, False: 2.55k]
  ------------------
  122|      0|            ReportError("aiScene::%s[%i] is nullptr (aiScene::%s is %i)",
  123|      0|                    firstName, i, secondName, size);
  124|      0|        }
  125|  2.55k|        Validate(parray[i]);
  126|  2.55k|    }
  127|  1.48k|}

_ZN10ODDLParser5Value8IteratorC2EPS0_:
   39|      2|        m_start(start),
   40|      2|        m_current(start) {
   41|       |    // empty
   42|      2|}

_ZN4pugi13xml_attributeC2Ev:
 5234|      2|	PUGI_IMPL_FN xml_attribute::xml_attribute(): _attr(nullptr)
 5235|      2|	{
 5236|      2|	}
_ZN4pugi8xml_nodeC2Ev:
 5593|  6.97k|	PUGI_IMPL_FN xml_node::xml_node(): _root(nullptr)
 5594|  6.97k|	{
 5595|  6.97k|	}
_ZN4pugi10xpath_nodeC2Ev:
12714|      2|	{
12715|      2|	}
_ZN4pugi14xpath_node_setC2Ev:
12821|      2|	PUGI_IMPL_FN xpath_node_set::xpath_node_set(): _type(type_unsorted), _begin(_storage), _end(_storage)
12822|      2|	{
12823|      2|	}

_ZN9rapidjson12CrtAllocator6MallocEm:
   86|  15.9k|    void* Malloc(size_t size) { 
   87|  15.9k|        if (size) //  behavior of malloc(0) is implementation defined.
  ------------------
  |  Branch (87:13): [True: 15.9k, False: 0]
  ------------------
   88|  15.9k|            return RAPIDJSON_MALLOC(size);
  ------------------
  |  |  696|  15.9k|#define RAPIDJSON_MALLOC(size) std::malloc(size)
  ------------------
   89|      0|        else
   90|      0|            return NULL; // standardize to returning NULL.
   91|  15.9k|    }
_ZN9rapidjson12CrtAllocator7ReallocEPvmm:
   92|  24.0k|    void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
   93|  24.0k|        (void)originalSize;
   94|  24.0k|        if (newSize == 0) {
  ------------------
  |  Branch (94:13): [True: 0, False: 24.0k]
  ------------------
   95|      0|            RAPIDJSON_FREE(originalPtr);
  ------------------
  |  |  704|      0|#define RAPIDJSON_FREE(ptr) std::free(ptr)
  ------------------
   96|      0|            return NULL;
   97|      0|        }
   98|  24.0k|        return RAPIDJSON_REALLOC(originalPtr, newSize);
  ------------------
  |  |  700|  24.0k|#define RAPIDJSON_REALLOC(ptr, new_size) std::realloc(ptr, new_size)
  ------------------
   99|  24.0k|    }
_ZN9rapidjson12CrtAllocator4FreeEPv:
  100|  42.0k|    static void Free(void *ptr) RAPIDJSON_NOEXCEPT { RAPIDJSON_FREE(ptr); }
  ------------------
  |  |  704|  42.0k|#define RAPIDJSON_FREE(ptr) std::free(ptr)
  ------------------
_ZN9rapidjson19MemoryPoolAllocatorINS_12CrtAllocatorEE12GetChunkHeadEPNS2_10SharedDataE:
  151|  8.71k|    {
  152|  8.71k|        return reinterpret_cast<ChunkHeader*>(reinterpret_cast<uint8_t*>(shared) + SIZEOF_SHARED_DATA);
  153|  8.71k|    }
_ZN9rapidjson19MemoryPoolAllocatorINS_12CrtAllocatorEE5ClearEv:
  277|  8.71k|    void Clear() RAPIDJSON_NOEXCEPT {
  278|  8.71k|        RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
  ------------------
  |  |  687|  8.71k|#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
  |  |  ------------------
  |  |  |  |  437|  8.71k|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  ------------------
  ------------------
  |  Branch (278:9): [True: 8.71k, False: 0]
  ------------------
  279|  15.9k|        for (;;) {
  280|  15.9k|            ChunkHeader* c = shared_->chunkHead;
  281|  15.9k|            if (!c->next) {
  ------------------
  |  Branch (281:17): [True: 8.71k, False: 7.19k]
  ------------------
  282|  8.71k|                break;
  283|  8.71k|            }
  284|  7.19k|            shared_->chunkHead = c->next;
  285|  7.19k|            baseAllocator_->Free(c);
  286|  7.19k|        }
  287|  8.71k|        shared_->chunkHead->size = 0;
  288|  8.71k|    }
_ZN9rapidjson19MemoryPoolAllocatorINS_12CrtAllocatorEE6MallocEm:
  321|  1.73M|    void* Malloc(size_t size) {
  322|  1.73M|        RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
  ------------------
  |  |  687|  1.73M|#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
  |  |  ------------------
  |  |  |  |  437|  1.73M|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  ------------------
  ------------------
  |  Branch (322:9): [True: 1.73M, False: 0]
  ------------------
  323|  1.73M|        if (!size)
  ------------------
  |  Branch (323:13): [True: 0, False: 1.73M]
  ------------------
  324|      0|            return NULL;
  325|       |
  326|  1.73M|        size = RAPIDJSON_ALIGN(size);
  ------------------
  |  |  307|  1.73M|#define RAPIDJSON_ALIGN(x) (((x) + static_cast<size_t>(7u)) & ~static_cast<size_t>(7u))
  ------------------
  327|  1.73M|        if (RAPIDJSON_UNLIKELY(shared_->chunkHead->size + size > shared_->chunkHead->capacity))
  ------------------
  |  |  505|  1.73M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 7.19k, False: 1.72M]
  |  |  ------------------
  ------------------
  328|  7.19k|            if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size))
  ------------------
  |  Branch (328:17): [True: 0, False: 7.19k]
  |  Branch (328:27): [True: 7.04k, False: 156]
  ------------------
  329|      0|                return NULL;
  330|       |
  331|  1.73M|        void *buffer = GetChunkBuffer(shared_) + shared_->chunkHead->size;
  332|  1.73M|        shared_->chunkHead->size += size;
  333|  1.73M|        return buffer;
  334|  1.73M|    }
_ZN9rapidjson19MemoryPoolAllocatorINS_12CrtAllocatorEE8AddChunkEm:
  390|  7.19k|    bool AddChunk(size_t capacity) {
  391|  7.19k|        if (!baseAllocator_)
  ------------------
  |  Branch (391:13): [True: 0, False: 7.19k]
  ------------------
  392|      0|            shared_->ownBaseAllocator = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)();
  ------------------
  |  |  712|      0|#define RAPIDJSON_NEW(TypeName) new TypeName
  ------------------
  393|  7.19k|        if (ChunkHeader* chunk = static_cast<ChunkHeader*>(baseAllocator_->Malloc(SIZEOF_CHUNK_HEADER + capacity))) {
  ------------------
  |  Branch (393:26): [True: 7.19k, False: 0]
  ------------------
  394|  7.19k|            chunk->capacity = capacity;
  395|  7.19k|            chunk->size = 0;
  396|  7.19k|            chunk->next = shared_->chunkHead;
  397|  7.19k|            shared_->chunkHead = chunk;
  398|  7.19k|            return true;
  399|  7.19k|        }
  400|      0|        else
  401|      0|            return false;
  402|  7.19k|    }
_ZN9rapidjson19MemoryPoolAllocatorINS_12CrtAllocatorEE14GetChunkBufferEPNS2_10SharedDataE:
  155|  1.73M|    {
  156|  1.73M|        return reinterpret_cast<uint8_t*>(shared->chunkHead) + SIZEOF_CHUNK_HEADER;
  157|  1.73M|    }
_ZN9rapidjson6MallocINS_13GenericMemberINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEES6_EEPT_RT0_m:
  443|  1.37M|{
  444|       |    return Realloc<T, A>(a, NULL, 0, n);
  445|  1.37M|}
_ZN9rapidjson7ReallocINS_13GenericMemberINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEES6_EEPT_RT0_S9_mm:
  436|  1.37M|{
  437|  1.37M|    RAPIDJSON_NOEXCEPT_ASSERT(old_n <= (std::numeric_limits<size_t>::max)() / sizeof(T) && new_n <= (std::numeric_limits<size_t>::max)() / sizeof(T));
  ------------------
  |  |  687|  1.37M|#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
  |  |  ------------------
  |  |  |  |  437|  1.37M|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  ------------------
  ------------------
  |  Branch (437:5): [True: 1.37M, False: 0]
  |  Branch (437:5): [True: 1.37M, False: 0]
  |  Branch (437:5): [True: 1.37M, False: 0]
  ------------------
  438|  1.37M|    return static_cast<T*>(a.Realloc(old_p, old_n * sizeof(T), new_n * sizeof(T)));
  439|  1.37M|}
_ZN9rapidjson19MemoryPoolAllocatorINS_12CrtAllocatorEE7ReallocEPvmm:
  337|  1.37M|    void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
  338|  1.37M|        if (originalPtr == 0)
  ------------------
  |  Branch (338:13): [True: 1.37M, False: 0]
  ------------------
  339|  1.37M|            return Malloc(newSize);
  340|       |
  341|      0|        RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
  ------------------
  |  |  687|      0|#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
  |  |  ------------------
  |  |  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  ------------------
  ------------------
  |  Branch (341:9): [True: 0, False: 0]
  ------------------
  342|      0|        if (newSize == 0)
  ------------------
  |  Branch (342:13): [True: 0, False: 0]
  ------------------
  343|      0|            return NULL;
  344|       |
  345|      0|        originalSize = RAPIDJSON_ALIGN(originalSize);
  ------------------
  |  |  307|      0|#define RAPIDJSON_ALIGN(x) (((x) + static_cast<size_t>(7u)) & ~static_cast<size_t>(7u))
  ------------------
  346|      0|        newSize = RAPIDJSON_ALIGN(newSize);
  ------------------
  |  |  307|      0|#define RAPIDJSON_ALIGN(x) (((x) + static_cast<size_t>(7u)) & ~static_cast<size_t>(7u))
  ------------------
  347|       |
  348|       |        // Do not shrink if new size is smaller than original
  349|      0|        if (originalSize >= newSize)
  ------------------
  |  Branch (349:13): [True: 0, False: 0]
  ------------------
  350|      0|            return originalPtr;
  351|       |
  352|       |        // Simply expand it if it is the last allocation and there is sufficient space
  353|      0|        if (originalPtr == GetChunkBuffer(shared_) + shared_->chunkHead->size - originalSize) {
  ------------------
  |  Branch (353:13): [True: 0, False: 0]
  ------------------
  354|      0|            size_t increment = static_cast<size_t>(newSize - originalSize);
  355|      0|            if (shared_->chunkHead->size + increment <= shared_->chunkHead->capacity) {
  ------------------
  |  Branch (355:17): [True: 0, False: 0]
  ------------------
  356|      0|                shared_->chunkHead->size += increment;
  357|      0|                return originalPtr;
  358|      0|            }
  359|      0|        }
  360|       |
  361|       |        // Realloc process: allocate and copy memory, do not free original buffer.
  362|      0|        if (void* newBuffer = Malloc(newSize)) {
  ------------------
  |  Branch (362:19): [True: 0, False: 0]
  ------------------
  363|      0|            if (originalSize)
  ------------------
  |  Branch (363:17): [True: 0, False: 0]
  ------------------
  364|      0|                std::memcpy(newBuffer, originalPtr, originalSize);
  365|      0|            return newBuffer;
  366|      0|        }
  367|      0|        else
  368|      0|            return NULL;
  369|      0|    }
_ZN9rapidjson19MemoryPoolAllocatorINS_12CrtAllocatorEEC2EmPS1_:
  171|  8.71k|        chunk_capacity_(chunkSize),
  172|  8.71k|        baseAllocator_(baseAllocator ? baseAllocator : RAPIDJSON_NEW(BaseAllocator)()),
  ------------------
  |  |  712|  8.71k|#define RAPIDJSON_NEW(TypeName) new TypeName
  ------------------
  |  Branch (172:24): [True: 0, False: 8.71k]
  ------------------
  173|  8.71k|        shared_(static_cast<SharedData*>(baseAllocator_ ? baseAllocator_->Malloc(SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER) : 0))
  ------------------
  |  Branch (173:42): [True: 8.71k, False: 0]
  ------------------
  174|  8.71k|    {
  175|  8.71k|        RAPIDJSON_ASSERT(baseAllocator_ != 0);
  ------------------
  |  |  437|  8.71k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (175:9): [True: 8.71k, False: 0]
  ------------------
  176|  8.71k|        RAPIDJSON_ASSERT(shared_ != 0);
  ------------------
  |  |  437|  8.71k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (176:9): [True: 8.71k, False: 0]
  ------------------
  177|  8.71k|        if (baseAllocator) {
  ------------------
  |  Branch (177:13): [True: 0, False: 8.71k]
  ------------------
  178|      0|            shared_->ownBaseAllocator = 0;
  179|      0|        }
  180|  8.71k|        else {
  181|  8.71k|            shared_->ownBaseAllocator = baseAllocator_;
  182|  8.71k|        }
  183|  8.71k|        shared_->chunkHead = GetChunkHead(shared_);
  184|  8.71k|        shared_->chunkHead->capacity = 0;
  185|  8.71k|        shared_->chunkHead->size = 0;
  186|  8.71k|        shared_->chunkHead->next = 0;
  187|  8.71k|        shared_->ownBuffer = true;
  188|  8.71k|        shared_->refcount = 1;
  189|  8.71k|    }
_ZN9rapidjson19MemoryPoolAllocatorINS_12CrtAllocatorEED2Ev:
  259|  8.71k|    ~MemoryPoolAllocator() RAPIDJSON_NOEXCEPT {
  260|  8.71k|        if (!shared_) {
  ------------------
  |  Branch (260:13): [True: 0, False: 8.71k]
  ------------------
  261|       |            // do nothing if moved
  262|      0|            return;
  263|      0|        }
  264|  8.71k|        if (shared_->refcount > 1) {
  ------------------
  |  Branch (264:13): [True: 0, False: 8.71k]
  ------------------
  265|      0|            --shared_->refcount;
  266|      0|            return;
  267|      0|        }
  268|  8.71k|        Clear();
  269|  8.71k|        BaseAllocator *a = shared_->ownBaseAllocator;
  270|  8.71k|        if (shared_->ownBuffer) {
  ------------------
  |  Branch (270:13): [True: 8.71k, False: 0]
  ------------------
  271|  8.71k|            baseAllocator_->Free(shared_);
  272|  8.71k|        }
  273|  8.71k|        RAPIDJSON_DELETE(a);
  ------------------
  |  |  716|  8.71k|#define RAPIDJSON_DELETE(x) delete x
  ------------------
  274|  8.71k|    }

_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE6IsBoolEv:
 1115|  16.8k|    bool IsBool()   const { return (data_.f.flags & kBoolFlag) != 0; }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE7GetBoolEv:
 1176|  8.43k|    bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }
  ------------------
  |  |  437|  8.43k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1176:28): [True: 8.43k, False: 0]
  ------------------
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE8IsNumberEv:
 1118|   334k|    bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE9GetDoubleEv:
 1825|   152k|    double GetDouble() const {
 1826|   152k|        RAPIDJSON_ASSERT(IsNumber());
  ------------------
  |  |  437|   152k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1826:9): [True: 152k, False: 0]
  ------------------
 1827|   152k|        if ((data_.f.flags & kDoubleFlag) != 0)                return data_.n.d;   // exact type, no conversion.
  ------------------
  |  Branch (1827:13): [True: 128k, False: 23.4k]
  ------------------
 1828|  23.4k|        if ((data_.f.flags & kIntFlag) != 0)                   return data_.n.i.i; // int -> double
  ------------------
  |  Branch (1828:13): [True: 23.3k, False: 57]
  ------------------
 1829|     57|        if ((data_.f.flags & kUintFlag) != 0)                  return data_.n.u.u; // unsigned -> double
  ------------------
  |  Branch (1829:13): [True: 6, False: 51]
  ------------------
 1830|     51|        if ((data_.f.flags & kInt64Flag) != 0)                 return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
  ------------------
  |  Branch (1830:13): [True: 44, False: 7]
  ------------------
 1831|      7|        RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0);  return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
  ------------------
  |  |  437|      7|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1831:9): [True: 7, False: 0]
  ------------------
 1832|      7|    }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE8IsStringEv:
 1124|  11.6M|    bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE9GetStringEv:
 1853|   743k|    const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return DataString(data_); }
  ------------------
  |  |  437|   743k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1853:35): [True: 743k, False: 0]
  ------------------
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE10DataStringERKNS6_4DataE:
 2107|   743k|    static RAPIDJSON_FORCEINLINE const Ch* DataString(const Data& data) {
 2108|   743k|        return (data.f.flags & kInlineStrFlag) ? data.ss.str : RAPIDJSON_GETPOINTER(Ch, data.s.str);
  ------------------
  |  |  347|   743k|#define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast<type *>(reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF))))
  |  |  ------------------
  |  |  |  |  320|   743k|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  |  |  ------------------
  ------------------
  |  Branch (2108:16): [True: 0, False: 743k]
  ------------------
 2109|   743k|    }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE15GetStringLengthEv:
 1858|  5.27M|    SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return DataStringLength(data_); }
  ------------------
  |  |  437|  5.27M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1858:40): [True: 5.27M, False: 0]
  ------------------
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE16DataStringLengthERKNS6_4DataE:
 2110|  5.27M|    static RAPIDJSON_FORCEINLINE SizeType DataStringLength(const Data& data) {
 2111|  5.27M|        return (data.f.flags & kInlineStrFlag) ? data.ss.GetLength() : data.s.length;
  ------------------
  |  Branch (2111:16): [True: 0, False: 5.27M]
  ------------------
 2112|  5.27M|    }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE8IsUint64Ev:
 1122|  34.3k|    bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE9GetUint64Ev:
 1820|  34.3k|    uint64_t GetUint64() const  { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }
  ------------------
  |  |  437|  34.3k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1820:35): [True: 34.3k, False: 0]
  ------------------
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE7IsInt64Ev:
 1121|     22|    bool IsInt64()  const { return (data_.f.flags & kInt64Flag) != 0; }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE8GetInt64Ev:
 1819|      6|    int64_t GetInt64() const    { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }
  ------------------
  |  |  437|      6|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1819:35): [True: 6, False: 0]
  ------------------
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE8IsObjectEv:
 1116|  4.40M|    bool IsObject() const { return data_.f.flags == kObjectFlag; }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE10FindMemberEPKc:
 1337|   356k|    MemberIterator FindMember(const Ch* name) {
 1338|   356k|        GenericValue n(StringRef(name));
 1339|   356k|        return FindMember(n);
 1340|   356k|    }
_ZN9rapidjson9StringRefIcEENS_16GenericStringRefIT_EEPKS2_:
  454|   356k|inline GenericStringRef<CharType> StringRef(const CharType* str) {
  455|   356k|    return GenericStringRef<CharType>(str);
  456|   356k|}
_ZN9rapidjson16GenericStringRefIcE13NotNullStrLenEPKc:
  423|   356k|    SizeType NotNullStrLen(const CharType* str) {
  424|   356k|        RAPIDJSON_ASSERT(str != 0);
  ------------------
  |  |  437|   356k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (424:9): [True: 356k, False: 0]
  ------------------
  425|   356k|        return internal::StrLen(str);
  426|   356k|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE12SetStringRawENS_16GenericStringRefIcEE:
 2435|  6.15M|    void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
 2436|  6.15M|        data_.f.flags = kConstStringFlag;
 2437|  6.15M|        SetStringPointer(s);
 2438|  6.15M|        data_.s.length = s.length;
 2439|  6.15M|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE16SetStringPointerEPKc:
 2115|  6.15M|    RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
  ------------------
  |  |  346|  6.15M|#define RAPIDJSON_SETPOINTER(type, p, x) (p = reinterpret_cast<type *>((reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0xFFFF0000, 0x00000000))) | reinterpret_cast<uintptr_t>(reinterpret_cast<const void*>(x))))
  |  |  ------------------
  |  |  |  |  320|  6.15M|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  |  |  ------------------
  ------------------
_ZNK9rapidjson16GenericStringRefIcEcvPKcEv:
  417|  6.15M|    operator const Ch *() const { return s; }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE18GetElementsPointerEv:
 2116|   357k|    RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
  ------------------
  |  |  347|   357k|#define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast<type *>(reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF))))
  |  |  ------------------
  |  |  |  |  320|   357k|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  |  |  ------------------
  ------------------
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE17GetMembersPointerEv:
 2118|  3.60M|    RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
  ------------------
  |  |  347|  3.60M|#define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast<type *>(reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF))))
  |  |  ------------------
  |  |  |  |  320|  3.60M|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  |  |  ------------------
  ------------------
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE10FindMemberIS5_EEPNS_13GenericMemberIS2_S5_EERKNS0_IS2_T_EE:
 1358|   356k|    MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
 1359|   356k|        RAPIDJSON_ASSERT(IsObject());
  ------------------
  |  |  437|   356k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1359:9): [True: 356k, False: 0]
  ------------------
 1360|   356k|        RAPIDJSON_ASSERT(name.IsString());
  ------------------
  |  |  437|   356k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1360:9): [True: 356k, False: 0]
  ------------------
 1361|   356k|        return DoFindMember(name);
 1362|   356k|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE12DoFindMemberIS5_EEPNS_13GenericMemberIS2_S5_EERKNS0_IS2_T_EE:
 2282|   356k|    MemberIterator DoFindMember(const GenericValue<Encoding, SourceAllocator>& name) {
 2283|   356k|        MemberIterator member = MemberBegin();
 2284|  2.83M|        for ( ; member != MemberEnd(); ++member)
  ------------------
  |  Branch (2284:17): [True: 2.62M, False: 211k]
  ------------------
 2285|  2.62M|            if (name.StringEqual(member->name))
  ------------------
  |  Branch (2285:17): [True: 145k, False: 2.47M]
  ------------------
 2286|   145k|                break;
 2287|   356k|        return member;
 2288|   356k|    }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE11StringEqualIS5_EEbRKNS0_IS2_T_EE:
 2466|  2.62M|    bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {
 2467|  2.62M|        RAPIDJSON_ASSERT(IsString());
  ------------------
  |  |  437|  2.62M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (2467:9): [True: 2.62M, False: 0]
  ------------------
 2468|  2.62M|        RAPIDJSON_ASSERT(rhs.IsString());
  ------------------
  |  |  437|  2.62M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (2468:9): [True: 2.62M, False: 0]
  ------------------
 2469|       |
 2470|  2.62M|        const SizeType len1 = GetStringLength();
 2471|  2.62M|        const SizeType len2 = rhs.GetStringLength();
 2472|  2.62M|        if(len1 != len2) { return false; }
  ------------------
  |  Branch (2472:12): [True: 2.29M, False: 333k]
  ------------------
 2473|       |
 2474|   333k|        const Ch* const str1 = GetString();
 2475|   333k|        const Ch* const str2 = rhs.GetString();
 2476|   333k|        if(str1 == str2) { return true; } // fast path for constant string
  ------------------
  |  Branch (2476:12): [True: 0, False: 333k]
  ------------------
 2477|       |
 2478|   333k|        return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
 2479|   333k|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE9MemberEndEv:
 1277|  3.23M|    MemberIterator MemberEnd()              { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }
  ------------------
  |  |  437|  3.23M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1277:47): [True: 3.23M, False: 0]
  ------------------
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE6IsUintEv:
 1120|  49.7k|    bool IsUint()   const { return (data_.f.flags & kUintFlag) != 0; }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE7IsArrayEv:
 1117|   549k|    bool IsArray()  const { return data_.f.flags == kArrayFlag; }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE11MemberBeginEv:
 1274|   365k|    MemberIterator MemberBegin()            { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }
  ------------------
  |  |  437|   365k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1274:47): [True: 365k, False: 0]
  ------------------
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE4SizeEv:
 1643|  80.7k|    SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
  ------------------
  |  |  437|  80.7k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1643:29): [True: 80.7k, False: 0]
  ------------------
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEixEj:
 1668|   357k|    GenericValue& operator[](SizeType index) {
 1669|   357k|        RAPIDJSON_ASSERT(IsArray());
  ------------------
  |  |  437|   357k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1669:9): [True: 357k, False: 0]
  ------------------
 1670|   357k|        RAPIDJSON_ASSERT(index < data_.a.size);
  ------------------
  |  |  437|   357k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1670:9): [True: 357k, False: 0]
  ------------------
 1671|   357k|        return GetElementsPointer()[index];
 1672|   357k|    }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE8IsDoubleEv:
 1123|     16|    bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE11MemberCountEv:
 1191|  7.56k|    SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
  ------------------
  |  |  437|  7.56k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1191:36): [True: 7.56k, False: 0]
  ------------------
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE7GetUintEv:
 1818|  48.9k|    unsigned GetUint() const    { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag);  return data_.n.u.u;   }
  ------------------
  |  |  437|  48.9k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1818:35): [True: 48.9k, False: 0]
  ------------------
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE5IsIntEv:
 1119|  8.93k|    bool IsInt()    const { return (data_.f.flags & kIntFlag) != 0; }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE6GetIntEv:
 1817|  8.91k|    int GetInt() const          { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag);   return data_.n.i.i;   }
  ------------------
  |  |  437|  8.91k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1817:35): [True: 8.91k, False: 0]
  ------------------
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE7SetNullEv:
 1169|  8.71k|    GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E7DestroyEv:
 2877|  8.71k|    void Destroy() {
 2878|  8.71k|        RAPIDJSON_DELETE(ownAllocator_);
  ------------------
  |  |  716|  8.71k|#define RAPIDJSON_DELETE(x) delete x
  ------------------
 2879|  8.71k|    }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E11ParseInsituEPc:
 2694|  8.71k|    GenericDocument& ParseInsitu(Ch* str) {
 2695|  8.71k|        return ParseInsitu<kParseDefaultFlags>(str);
 2696|  8.71k|    }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E11ParseInsituILj0EEERS6_Pc:
 2685|  8.71k|    GenericDocument& ParseInsitu(Ch* str) {
 2686|  8.71k|        GenericInsituStringStream<Encoding> s(str);
 2687|  8.71k|        return ParseStream<parseFlags | kParseInsituFlag>(s);
 2688|  8.71k|    }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E11ParseStreamILj1ENS_25GenericInsituStringStreamIS2_EEEERS6_RT0_:
 2661|  8.71k|    GenericDocument& ParseStream(InputStream& is) {
 2662|  8.71k|        return ParseStream<parseFlags, Encoding, InputStream>(is);
 2663|  8.71k|    }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E11ParseStreamILj1ES2_NS_25GenericInsituStringStreamIS2_EEEERS6_RT1_:
 2642|  8.71k|    GenericDocument& ParseStream(InputStream& is) {
 2643|  8.71k|        GenericReader<SourceEncoding, Encoding, StackAllocator> reader(
 2644|  8.71k|            stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
  ------------------
  |  Branch (2644:13): [True: 0, False: 8.71k]
  ------------------
 2645|  8.71k|        ClearStackOnExit scope(*this);
 2646|  8.71k|        parseResult_ = reader.template Parse<parseFlags>(is, *this);
 2647|  8.71k|        if (parseResult_) {
  ------------------
  |  Branch (2647:13): [True: 5.89k, False: 2.82k]
  ------------------
 2648|  5.89k|            RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
  ------------------
  |  |  437|  5.89k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (2648:13): [True: 5.89k, False: 0]
  ------------------
 2649|  5.89k|            ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
 2650|  5.89k|        }
 2651|  8.71k|        return *this;
 2652|  8.71k|    }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E10ClearStackEv:
 2868|  8.71k|    void ClearStack() {
 2869|  8.71k|        if (Allocator::kNeedFree)
  ------------------
  |  Branch (2869:13): [Folded, False: 8.71k]
  ------------------
 2870|      0|            while (stack_.GetSize() > 0)    // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
  ------------------
  |  Branch (2870:20): [True: 0, False: 0]
  ------------------
 2871|      0|                (stack_.template Pop<ValueType>(1))->~ValueType();
 2872|  8.71k|        else
 2873|  8.71k|            stack_.Clear();
 2874|  8.71k|        stack_.ShrinkToFit();
 2875|  8.71k|    }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E11StartObjectEv:
 2844|  3.89M|    bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E10StartArrayEv:
 2854|  5.66M|    bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E3KeyEPKcjb:
 2846|  5.68M|    bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E6StringEPKcjb:
 2836|  5.80M|    bool String(const Ch* str, SizeType length, bool copy) { 
 2837|  5.80M|        if (copy) 
  ------------------
  |  Branch (2837:13): [True: 0, False: 5.80M]
  ------------------
 2838|      0|            new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
 2839|  5.80M|        else
 2840|  5.80M|            new (stack_.template Push<ValueType>()) ValueType(str, length);
 2841|  5.80M|        return true;
 2842|  5.80M|    }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E12GetAllocatorEv:
 2795|  4.24M|    Allocator& GetAllocator() {
 2796|  4.24M|        RAPIDJSON_ASSERT(allocator_);
  ------------------
  |  |  437|  4.24M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (2796:9): [True: 4.24M, False: 0]
  ------------------
 2797|  4.24M|        return *allocator_;
 2798|  4.24M|    }
_ZN9rapidjson9StringRefIcEENS_16GenericStringRefIT_EEPKS2_m:
  474|  5.80M|inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
  475|  5.80M|    return GenericStringRef<CharType>(str, SizeType(length));
  476|  5.80M|}
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E9EndObjectEj:
 2848|  3.88M|    bool EndObject(SizeType memberCount) {
 2849|  3.88M|        typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
 2850|  3.88M|        stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
 2851|  3.88M|        return true;
 2852|  3.88M|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE12SetObjectRawEPNS_13GenericMemberIS2_S5_EEjRS5_:
 2415|  3.88M|    void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
 2416|  3.88M|        data_.f.flags = kObjectFlag;
 2417|  3.88M|        if (count) {
  ------------------
  |  Branch (2417:13): [True: 1.37M, False: 2.50M]
  ------------------
 2418|  1.37M|            Member* m = DoAllocMembers(count, allocator);
 2419|  1.37M|            SetMembersPointer(m);
 2420|  1.37M|            std::memcpy(static_cast<void*>(m), members, count * sizeof(Member));
 2421|       |#if RAPIDJSON_USE_MEMBERSMAP
 2422|       |            Map* &map = GetMap(m);
 2423|       |            MapIterator* mit = GetMapIterators(map);
 2424|       |            for (SizeType i = 0; i < count; i++) {
 2425|       |                new (&mit[i]) MapIterator(map->insert(MapPair(m[i].name.data_, i)));
 2426|       |            }
 2427|       |#endif
 2428|  1.37M|        }
 2429|  2.50M|        else
 2430|  2.50M|            SetMembersPointer(0);
 2431|  3.88M|        data_.o.size = data_.o.capacity = count;
 2432|  3.88M|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE14DoAllocMembersEjRS5_:
 2268|  1.37M|    RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) {
 2269|  1.37M|        return Malloc<Member>(allocator, capacity);
 2270|  1.37M|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE17SetMembersPointerEPNS_13GenericMemberIS2_S5_EE:
 2119|  3.88M|    RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
  ------------------
  |  |  346|  3.88M|#define RAPIDJSON_SETPOINTER(type, p, x) (p = reinterpret_cast<type *>((reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0xFFFF0000, 0x00000000))) | reinterpret_cast<uintptr_t>(reinterpret_cast<const void*>(x))))
  |  |  ------------------
  |  |  |  |  320|  3.88M|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  |  |  ------------------
  ------------------
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E8EndArrayEj:
 2856|   361k|    bool EndArray(SizeType elementCount) {
 2857|   361k|        ValueType* elements = stack_.template Pop<ValueType>(elementCount);
 2858|   361k|        stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
 2859|   361k|        return true;
 2860|   361k|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE11SetArrayRawEPS6_jRS5_:
 2402|   361k|    void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
 2403|   361k|        data_.f.flags = kArrayFlag;
 2404|   361k|        if (count) {
  ------------------
  |  Branch (2404:13): [True: 357k, False: 3.85k]
  ------------------
 2405|   357k|            GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
 2406|   357k|            SetElementsPointer(e);
 2407|   357k|            std::memcpy(static_cast<void*>(e), values, count * sizeof(GenericValue));
 2408|   357k|        }
 2409|  3.85k|        else
 2410|  3.85k|            SetElementsPointer(0);
 2411|   361k|        data_.a.size = data_.a.capacity = count;
 2412|   361k|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE18SetElementsPointerEPS6_:
 2117|   361k|    RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
  ------------------
  |  |  346|   361k|#define RAPIDJSON_SETPOINTER(type, p, x) (p = reinterpret_cast<type *>((reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0xFFFF0000, 0x00000000))) | reinterpret_cast<uintptr_t>(reinterpret_cast<const void*>(x))))
  |  |  ------------------
  |  |  |  |  320|   361k|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  |  |  ------------------
  ------------------
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E4NullEv:
 2820|  5.72k|    bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E4BoolEb:
 2821|  56.6k|    bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E6DoubleEd:
 2826|   468k|    bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E5Int64El:
 2824|  59.8k|    bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E6Uint64Em:
 2825|  15.0k|    bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E3IntEi:
 2822|   139k|    bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E4UintEj:
 2823|  25.7M|    bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEaSERS6_:
  921|  5.89k|    GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
  922|  5.89k|        if (RAPIDJSON_LIKELY(this != &rhs)) {
  ------------------
  |  |  492|  5.89k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 5.89k, False: 0]
  |  |  ------------------
  ------------------
  923|       |            // Can't destroy "this" before assigning "rhs", otherwise "rhs"
  924|       |            // could be used after free if it's an sub-Value of "this",
  925|       |            // hence the temporary danse.
  926|  5.89k|            GenericValue temp;
  927|  5.89k|            temp.RawAssign(rhs);
  928|  5.89k|            this->~GenericValue();
  929|  5.89k|            RawAssign(temp);
  930|  5.89k|        }
  931|  5.89k|        return *this;
  932|  5.89k|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE9RawAssignERS6_:
 2459|  11.7k|    void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
 2460|  11.7k|        data_ = rhs.data_;
 2461|       |        // data_.f.flags = rhs.data_.f.flags;
 2462|  11.7k|        rhs.data_.f.flags = kNullFlag;
 2463|  11.7k|    }
_ZNK9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E13HasParseErrorEv:
 2771|  8.71k|    bool HasParseError() const { return parseResult_.IsError(); }
_ZNK9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E14GetErrorOffsetEv:
 2777|  2.82k|    size_t GetErrorOffset() const { return parseResult_.Offset(); }
_ZNK9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E13GetParseErrorEv:
 2774|  2.82k|    ParseErrorCode GetParseError() const { return parseResult_.Code(); }
_ZN9rapidjson16GenericStringRefIcEC2EPKc:
  400|   356k|        : s(str), length(NotNullStrLen(str)) {}
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2ENS_16GenericStringRefIcEE:
  840|   356k|    explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }
_ZN9rapidjson16GenericStringRefIcEC2ERKS1_:
  414|   356k|    GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEED2Ev:
  880|   385k|    ~GenericValue() {
  881|       |        // With RAPIDJSON_USE_MEMBERSMAP, the maps need to be destroyed to release
  882|       |        // their Allocator if it's refcounted (e.g. MemoryPoolAllocator).
  883|   385k|        if (Allocator::kNeedFree || (RAPIDJSON_USE_MEMBERSMAP+0 &&
  ------------------
  |  |  180|      0|#define RAPIDJSON_USE_MEMBERSMAP 0 // not by default
  ------------------
  |  Branch (883:13): [Folded, False: 0]
  |  Branch (883:38): [Folded, False: 0]
  ------------------
  884|      0|                                     internal::IsRefCounted<Allocator>::Value)) {
  ------------------
  |  Branch (884:38): [True: 0, Folded]
  ------------------
  885|      0|            switch(data_.f.flags) {
  886|      0|            case kArrayFlag:
  ------------------
  |  Branch (886:13): [True: 0, False: 0]
  ------------------
  887|      0|                {
  888|      0|                    GenericValue* e = GetElementsPointer();
  889|      0|                    for (GenericValue* v = e; v != e + data_.a.size; ++v)
  ------------------
  |  Branch (889:47): [True: 0, False: 0]
  ------------------
  890|      0|                        v->~GenericValue();
  891|      0|                    if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
  ------------------
  |  Branch (891:25): [Folded, False: 0]
  ------------------
  892|      0|                        Allocator::Free(e);
  893|      0|                    }
  894|      0|                }
  895|      0|                break;
  896|       |
  897|      0|            case kObjectFlag:
  ------------------
  |  Branch (897:13): [True: 0, False: 0]
  ------------------
  898|      0|                DoFreeMembers();
  899|      0|                break;
  900|       |
  901|      0|            case kCopyStringFlag:
  ------------------
  |  Branch (901:13): [True: 0, False: 0]
  ------------------
  902|      0|                if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
  ------------------
  |  Branch (902:21): [Folded, False: 0]
  ------------------
  903|      0|                    Allocator::Free(const_cast<Ch*>(GetStringPointer()));
  904|      0|                }
  905|      0|                break;
  906|       |
  907|      0|            default:
  ------------------
  |  Branch (907:13): [True: 0, False: 0]
  ------------------
  908|      0|                break;  // Do nothing for other types.
  909|      0|            }
  910|      0|        }
  911|   385k|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2Ev:
  690|  29.0k|    GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2ENS_4TypeE:
  720|  9.55M|    explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {
  721|  9.55M|        static const uint16_t defaultFlags[] = {
  722|  9.55M|            kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
  723|  9.55M|            kNumberAnyFlag
  724|  9.55M|        };
  725|  9.55M|        RAPIDJSON_NOEXCEPT_ASSERT(type >= kNullType && type <= kNumberType);
  ------------------
  |  |  687|  9.55M|#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
  |  |  ------------------
  |  |  |  |  437|  9.55M|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  ------------------
  ------------------
  |  Branch (725:9): [True: 9.55M, False: 0]
  |  Branch (725:9): [True: 9.55M, False: 0]
  |  Branch (725:9): [True: 9.55M, False: 0]
  ------------------
  726|  9.55M|        data_.f.flags = defaultFlags[type];
  727|       |
  728|       |        // Use ShortString to store empty string.
  729|  9.55M|        if (type == kStringType)
  ------------------
  |  Branch (729:13): [True: 0, False: 9.55M]
  ------------------
  730|      0|            data_.ss.SetLength(0);
  731|  9.55M|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2Ej:
  798|  25.7M|    explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {
  799|  25.7M|        data_.n.u64 = u; 
  800|  25.7M|        data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
  ------------------
  |  Branch (800:25): [True: 2.93k, False: 25.7M]
  ------------------
  801|  25.7M|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2Ei:
  792|   139k|    explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() {
  793|   139k|        data_.n.i64 = i;
  794|   139k|        data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
  ------------------
  |  Branch (794:25): [True: 1.56k, False: 137k]
  ------------------
  795|   139k|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2Ed:
  831|   468k|    explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2El:
  804|  59.8k|    explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() {
  805|  59.8k|        data_.n.i64 = i64;
  806|  59.8k|        data_.f.flags = kNumberInt64Flag;
  807|  59.8k|        if (i64 >= 0) {
  ------------------
  |  Branch (807:13): [True: 0, False: 59.8k]
  ------------------
  808|      0|            data_.f.flags |= kNumberUint64Flag;
  809|      0|            if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
  ------------------
  |  |  320|      0|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  ------------------
  |  Branch (809:17): [True: 0, False: 0]
  ------------------
  810|      0|                data_.f.flags |= kUintFlag;
  811|      0|            if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
  ------------------
  |  |  320|      0|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  ------------------
  |  Branch (811:17): [True: 0, False: 0]
  ------------------
  812|      0|                data_.f.flags |= kIntFlag;
  813|      0|        }
  814|  59.8k|        else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
  ------------------
  |  |  320|  59.8k|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  ------------------
  |  Branch (814:18): [True: 0, False: 59.8k]
  ------------------
  815|      0|            data_.f.flags |= kIntFlag;
  816|  59.8k|    }
_ZN9rapidjson16GenericStringRefIcEC2EPKcj:
  412|  5.80M|        : s(RAPIDJSON_LIKELY(str) ? str : emptyString), length(len) { RAPIDJSON_ASSERT(str != 0 || len == 0u); }
  ------------------
  |  |  492|  5.80M|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 5.80M, False: 0]
  |  |  ------------------
  ------------------
                      : s(RAPIDJSON_LIKELY(str) ? str : emptyString), length(len) { RAPIDJSON_ASSERT(str != 0 || len == 0u); }
  ------------------
  |  |  437|  5.80M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (412:71): [True: 5.80M, False: 0]
  |  Branch (412:71): [True: 0, False: 0]
  |  Branch (412:71): [True: 5.80M, False: 0]
  ------------------
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2Em:
  819|  15.0k|    explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() {
  820|  15.0k|        data_.n.u64 = u64;
  821|  15.0k|        data_.f.flags = kNumberUint64Flag;
  822|  15.0k|        if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
  ------------------
  |  |  320|  15.0k|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  ------------------
  |  Branch (822:13): [True: 11.4k, False: 3.59k]
  ------------------
  823|  11.4k|            data_.f.flags |= kInt64Flag;
  824|  15.0k|        if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
  ------------------
  |  |  320|  15.0k|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  ------------------
  |  Branch (824:13): [True: 0, False: 15.0k]
  ------------------
  825|      0|            data_.f.flags |= kUintFlag;
  826|  15.0k|        if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
  ------------------
  |  |  320|  15.0k|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  ------------------
  |  Branch (826:13): [True: 0, False: 15.0k]
  ------------------
  827|      0|            data_.f.flags |= kIntFlag;
  828|  15.0k|    }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_EC2EPS5_mPS4_:
 2527|  8.71k|        allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
 2528|  8.71k|    {
 2529|  8.71k|        if (!allocator_)
  ------------------
  |  Branch (2529:13): [True: 8.71k, False: 0]
  ------------------
 2530|  8.71k|            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
  ------------------
  |  |  712|  8.71k|#define RAPIDJSON_NEW(TypeName) new TypeName
  ------------------
 2531|  8.71k|    }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E16ClearStackOnExitC2ERS6_:
 2806|  8.71k|        explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2IbEET_PNS_8internal8EnableIfINS9_15RemoveSfinaeTagIPFRNS9_9SfinaeTagENS9_6IsSameIbS8_EEEE4TypeEvE4TypeE:
  785|  56.6k|        : data_() {
  786|       |            // safe-guard against failing SFINAE
  787|  56.6k|            RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value));
  ------------------
  |  |  447|  56.6k|   static_assert(x, RAPIDJSON_STRINGIFY(x))
  ------------------
  788|  56.6k|            data_.f.flags = b ? kTrueFlag : kFalseFlag;
  ------------------
  |  Branch (788:29): [True: 23.9k, False: 32.7k]
  ------------------
  789|  56.6k|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2EPKcj:
  837|  5.80M|    GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E16ClearStackOnExitD2Ev:
 2807|  8.71k|        ~ClearStackOnExit() { d_.ClearStack(); }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_ED2Ev:
 2548|  8.71k|    ~GenericDocument() {
 2549|       |        // Clear the ::ValueType before ownAllocator is destroyed, ~ValueType()
 2550|       |        // runs last and may access its elements or members which would be freed
 2551|       |        // with an allocator like MemoryPoolAllocator (CrtAllocator does not
 2552|       |        // free its data when destroyed, but MemoryPoolAllocator does).
 2553|  8.71k|        if (ownAllocator_) {
  ------------------
  |  Branch (2553:13): [True: 8.71k, False: 0]
  ------------------
 2554|  8.71k|            ValueType::SetNull();
 2555|  8.71k|        }
 2556|  8.71k|        Destroy();
 2557|  8.71k|    }

_ZN9rapidjson4UTF8IcE6EncodeINS_25GenericInsituStringStreamIS1_EEEEvRT_j:
  102|  3.06k|    static void Encode(OutputStream& os, unsigned codepoint) {
  103|  3.06k|        if (codepoint <= 0x7F) 
  ------------------
  |  Branch (103:13): [True: 2.07k, False: 991]
  ------------------
  104|  2.07k|            os.Put(static_cast<Ch>(codepoint & 0xFF));
  105|    991|        else if (codepoint <= 0x7FF) {
  ------------------
  |  Branch (105:18): [True: 193, False: 798]
  ------------------
  106|    193|            os.Put(static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF)));
  107|    193|            os.Put(static_cast<Ch>(0x80 | ((codepoint & 0x3F))));
  108|    193|        }
  109|    798|        else if (codepoint <= 0xFFFF) {
  ------------------
  |  Branch (109:18): [True: 350, False: 448]
  ------------------
  110|    350|            os.Put(static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF)));
  111|    350|            os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
  112|    350|            os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F)));
  113|    350|        }
  114|    448|        else {
  115|    448|            RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
  ------------------
  |  |  437|    448|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (115:13): [True: 448, False: 0]
  ------------------
  116|    448|            os.Put(static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF)));
  117|    448|            os.Put(static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F)));
  118|    448|            os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
  119|    448|            os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F)));
  120|    448|        }
  121|  3.06k|    }
_ZN9rapidjson10TranscoderINS_4UTF8IcEES2_E9TranscodeINS_25GenericInsituStringStreamIS2_EES6_EEbRT_RT0_:
  693|  40.0M|    static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) {
  694|  40.0M|        os.Put(is.Take());  // Just copy one code unit. This semantic is different from primary template class.
  695|  40.0M|        return true;
  696|  40.0M|    }

_ZN9rapidjson16GetParseError_EnENS_14ParseErrorCodeE:
   36|  2.82k|inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) {
   37|  2.82k|    switch (parseErrorCode) {
   38|      0|        case kParseErrorNone:                           return RAPIDJSON_ERROR_STRING("No error.");
  ------------------
  |  |   52|      0|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (38:9): [True: 0, False: 2.82k]
  ------------------
   39|       |
   40|     24|        case kParseErrorDocumentEmpty:                  return RAPIDJSON_ERROR_STRING("The document is empty.");
  ------------------
  |  |   52|     24|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (40:9): [True: 24, False: 2.79k]
  ------------------
   41|    224|        case kParseErrorDocumentRootNotSingular:        return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values.");
  ------------------
  |  |   52|    224|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (41:9): [True: 224, False: 2.59k]
  ------------------
   42|       |
   43|  1.07k|        case kParseErrorValueInvalid:                   return RAPIDJSON_ERROR_STRING("Invalid value.");
  ------------------
  |  |   52|  1.07k|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (43:9): [True: 1.07k, False: 1.75k]
  ------------------
   44|       |
   45|    156|        case kParseErrorObjectMissName:                 return RAPIDJSON_ERROR_STRING("Missing a name for object member.");
  ------------------
  |  |   52|    156|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (45:9): [True: 156, False: 2.66k]
  ------------------
   46|     70|        case kParseErrorObjectMissColon:                return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member.");
  ------------------
  |  |   52|     70|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (46:9): [True: 70, False: 2.75k]
  ------------------
   47|     98|        case kParseErrorObjectMissCommaOrCurlyBracket:  return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member.");
  ------------------
  |  |   52|     98|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (47:9): [True: 98, False: 2.72k]
  ------------------
   48|       |
   49|    938|        case kParseErrorArrayMissCommaOrSquareBracket:  return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element.");
  ------------------
  |  |   52|    938|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (49:9): [True: 938, False: 1.88k]
  ------------------
   50|       |
   51|     50|        case kParseErrorStringUnicodeEscapeInvalidHex:  return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string.");
  ------------------
  |  |   52|     50|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (51:9): [True: 50, False: 2.77k]
  ------------------
   52|     28|        case kParseErrorStringUnicodeSurrogateInvalid:  return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid.");
  ------------------
  |  |   52|     28|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (52:9): [True: 28, False: 2.79k]
  ------------------
   53|     14|        case kParseErrorStringEscapeInvalid:            return RAPIDJSON_ERROR_STRING("Invalid escape character in string.");
  ------------------
  |  |   52|     14|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (53:9): [True: 14, False: 2.80k]
  ------------------
   54|     86|        case kParseErrorStringMissQuotationMark:        return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string.");
  ------------------
  |  |   52|     86|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (54:9): [True: 86, False: 2.73k]
  ------------------
   55|     16|        case kParseErrorStringInvalidEncoding:          return RAPIDJSON_ERROR_STRING("Invalid encoding in string.");
  ------------------
  |  |   52|     16|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (55:9): [True: 16, False: 2.80k]
  ------------------
   56|       |
   57|      4|        case kParseErrorNumberTooBig:                   return RAPIDJSON_ERROR_STRING("Number too big to be stored in double.");
  ------------------
  |  |   52|      4|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (57:9): [True: 4, False: 2.81k]
  ------------------
   58|     12|        case kParseErrorNumberMissFraction:             return RAPIDJSON_ERROR_STRING("Miss fraction part in number.");
  ------------------
  |  |   52|     12|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (58:9): [True: 12, False: 2.80k]
  ------------------
   59|     30|        case kParseErrorNumberMissExponent:             return RAPIDJSON_ERROR_STRING("Miss exponent in number.");
  ------------------
  |  |   52|     30|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (59:9): [True: 30, False: 2.79k]
  ------------------
   60|       |
   61|      0|        case kParseErrorTermination:                    return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error.");
  ------------------
  |  |   52|      0|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (61:9): [True: 0, False: 2.82k]
  ------------------
   62|      0|        case kParseErrorUnspecificSyntaxError:          return RAPIDJSON_ERROR_STRING("Unspecific syntax error.");
  ------------------
  |  |   52|      0|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (62:9): [True: 0, False: 2.82k]
  ------------------
   63|       |
   64|      0|        default:                                        return RAPIDJSON_ERROR_STRING("Unknown error.");
  ------------------
  |  |   52|      0|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (64:9): [True: 0, False: 2.82k]
  ------------------
   65|  2.82k|    }
   66|  2.82k|}

_ZN9rapidjson11ParseResultC2Ev:
  111|  17.4k|    ParseResult() : code_(kParseErrorNone), offset_(0) {}
_ZNK9rapidjson11ParseResult4CodeEv:
  116|  2.82k|    ParseErrorCode Code() const { return code_; }
_ZNK9rapidjson11ParseResult6OffsetEv:
  118|  2.82k|    size_t Offset() const { return offset_; }
_ZNK9rapidjson11ParseResultcvMS0_KFbvEEv:
  121|  8.71k|    operator BooleanType() const { return !IsError() ? &ParseResult::IsError : NULL; }
  ------------------
  |  Branch (121:43): [True: 5.89k, False: 2.82k]
  ------------------
_ZNK9rapidjson11ParseResult7IsErrorEv:
  123|   128M|    bool IsError() const { return code_ != kParseErrorNone; }
_ZN9rapidjson11ParseResult5ClearEv:
  134|  8.71k|    void Clear() { Set(kParseErrorNone); }
_ZN9rapidjson11ParseResult3SetENS_14ParseErrorCodeEm:
  136|  11.5k|    void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; }

_ZN9rapidjson8internal5Pow10Ei:
   28|   469k|inline double Pow10(int n) {
   29|   469k|    static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes
   30|   469k|        1e+0,  
   31|   469k|        1e+1,  1e+2,  1e+3,  1e+4,  1e+5,  1e+6,  1e+7,  1e+8,  1e+9,  1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, 
   32|   469k|        1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40,
   33|   469k|        1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60,
   34|   469k|        1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80,
   35|   469k|        1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100,
   36|   469k|        1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120,
   37|   469k|        1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140,
   38|   469k|        1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160,
   39|   469k|        1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180,
   40|   469k|        1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200,
   41|   469k|        1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220,
   42|   469k|        1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240,
   43|   469k|        1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260,
   44|   469k|        1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280,
   45|   469k|        1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300,
   46|   469k|        1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308
   47|   469k|    };
   48|   469k|    RAPIDJSON_ASSERT(n >= 0 && n <= 308);
  ------------------
  |  |  437|   469k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (48:5): [True: 469k, False: 0]
  |  Branch (48:5): [True: 469k, False: 0]
  |  Branch (48:5): [True: 469k, False: 0]
  ------------------
   49|   469k|    return e[n];
   50|   469k|}

_ZNK9rapidjson8internal5StackINS_12CrtAllocatorEE11GetCapacityEv:
  179|  39.6k|    size_t GetCapacity() const { return static_cast<size_t>(stackEnd_ - stack_); }
_ZNK9rapidjson8internal5StackINS_12CrtAllocatorEE7GetSizeEv:
  178|  8.55M|    size_t GetSize() const { return static_cast<size_t>(stackTop_ - stack_); }
_ZN9rapidjson8internal5StackINS_12CrtAllocatorEE6ResizeEm:
  201|  24.0k|    void Resize(size_t newCapacity) {
  202|  24.0k|        const size_t size = GetSize();  // Backup the current size
  203|  24.0k|        stack_ = static_cast<char*>(allocator_->Realloc(stack_, GetCapacity(), newCapacity));
  204|  24.0k|        stackTop_ = stack_ + size;
  205|  24.0k|        stackEnd_ = stack_ + newCapacity;
  206|  24.0k|    }
_ZNK9rapidjson8internal5StackINS_12CrtAllocatorEE12HasAllocatorEv:
  168|  8.71k|    bool HasAllocator() const {
  169|  8.71k|        return allocator_ != 0;
  170|  8.71k|    }
_ZN9rapidjson8internal5StackINS_12CrtAllocatorEE5ClearEv:
   99|  17.4k|    void Clear() { stackTop_ = stack_; }
_ZN9rapidjson8internal5StackINS_12CrtAllocatorEE11ShrinkToFitEv:
  101|  8.71k|    void ShrinkToFit() { 
  102|  8.71k|        if (Empty()) {
  ------------------
  |  Branch (102:13): [True: 8.71k, False: 0]
  ------------------
  103|       |            // If the stack is empty, completely deallocate the memory.
  104|  8.71k|            Allocator::Free(stack_); // NOLINT (+clang-analyzer-unix.Malloc)
  105|  8.71k|            stack_ = 0;
  106|  8.71k|            stackTop_ = 0;
  107|  8.71k|            stackEnd_ = 0;
  108|  8.71k|        }
  109|      0|        else
  110|      0|            Resize(GetSize());
  111|  8.71k|    }
_ZNK9rapidjson8internal5StackINS_12CrtAllocatorEE5EmptyEv:
  177|  8.71k|    bool Empty() const { return stackTop_ == stack_; }
_ZN9rapidjson8internal5StackINS_12CrtAllocatorEE4PushINS_12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorIS2_EEEEEEPT_m:
  123|  41.8M|    RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) {
  124|  41.8M|        Reserve<T>(count);
  125|  41.8M|        return PushUnsafe<T>(count);
  126|  41.8M|    }
_ZN9rapidjson8internal5StackINS_12CrtAllocatorEE7ReserveINS_12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorIS2_EEEEEEvm:
  116|  41.8M|    RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) {
  117|       |         // Expand the stack if needed
  118|  41.8M|        if (RAPIDJSON_UNLIKELY(static_cast<std::ptrdiff_t>(sizeof(T) * count) > (stackEnd_ - stackTop_)))
  ------------------
  |  |  505|  41.8M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 24.0k, False: 41.8M]
  |  |  ------------------
  ------------------
  119|  24.0k|            Expand<T>(count);
  120|  41.8M|    }
_ZN9rapidjson8internal5StackINS_12CrtAllocatorEE6ExpandINS_12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorIS2_EEEEEEvm:
  183|  24.0k|    void Expand(size_t count) {
  184|       |        // Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity.
  185|  24.0k|        size_t newCapacity;
  186|  24.0k|        if (stack_ == 0) {
  ------------------
  |  Branch (186:13): [True: 8.46k, False: 15.5k]
  ------------------
  187|  8.46k|            if (!allocator_)
  ------------------
  |  Branch (187:17): [True: 8.46k, False: 0]
  ------------------
  188|  8.46k|                ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
  ------------------
  |  |  712|  8.46k|#define RAPIDJSON_NEW(TypeName) new TypeName
  ------------------
  189|  8.46k|            newCapacity = initialCapacity_;
  190|  15.5k|        } else {
  191|  15.5k|            newCapacity = GetCapacity();
  192|  15.5k|            newCapacity += (newCapacity + 1) / 2;
  193|  15.5k|        }
  194|  24.0k|        size_t newSize = GetSize() + sizeof(T) * count;
  195|  24.0k|        if (newCapacity < newSize)
  ------------------
  |  Branch (195:13): [True: 0, False: 24.0k]
  ------------------
  196|      0|            newCapacity = newSize;
  197|       |
  198|  24.0k|        Resize(newCapacity);
  199|  24.0k|    }
_ZN9rapidjson8internal5StackINS_12CrtAllocatorEE10PushUnsafeINS_12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorIS2_EEEEEEPT_m:
  129|  41.8M|    RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) {
  130|  41.8M|        RAPIDJSON_ASSERT(stackTop_);
  ------------------
  |  |  437|  41.8M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (130:9): [True: 41.8M, False: 0]
  ------------------
  131|  41.8M|        RAPIDJSON_ASSERT(static_cast<std::ptrdiff_t>(sizeof(T) * count) <= (stackEnd_ - stackTop_));
  ------------------
  |  |  437|  41.8M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (131:9): [True: 41.8M, False: 0]
  ------------------
  132|  41.8M|        T* ret = reinterpret_cast<T*>(stackTop_);
  133|  41.8M|        stackTop_ += sizeof(T) * count;
  134|  41.8M|        return ret;
  135|  41.8M|    }
_ZN9rapidjson8internal5StackINS_12CrtAllocatorEE3PopINS_13GenericMemberINS_4UTF8IcEENS_19MemoryPoolAllocatorIS2_EEEEEEPT_m:
  138|  3.88M|    T* Pop(size_t count) {
  139|  3.88M|        RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T));
  ------------------
  |  |  437|  3.88M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (139:9): [True: 3.88M, False: 0]
  ------------------
  140|  3.88M|        stackTop_ -= count * sizeof(T);
  141|  3.88M|        return reinterpret_cast<T*>(stackTop_);
  142|  3.88M|    }
_ZN9rapidjson8internal5StackINS_12CrtAllocatorEE3TopINS_12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorIS2_EEEEEEPT_v:
  145|  4.24M|    T* Top() { 
  146|  4.24M|        RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
  ------------------
  |  |  437|  4.24M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (146:9): [True: 4.24M, False: 0]
  ------------------
  147|  4.24M|        return reinterpret_cast<T*>(stackTop_ - sizeof(T));
  148|  4.24M|    }
_ZN9rapidjson8internal5StackINS_12CrtAllocatorEE3PopINS_12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorIS2_EEEEEEPT_m:
  138|   367k|    T* Pop(size_t count) {
  139|   367k|        RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T));
  ------------------
  |  |  437|   367k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (139:9): [True: 367k, False: 0]
  ------------------
  140|   367k|        stackTop_ -= count * sizeof(T);
  141|   367k|        return reinterpret_cast<T*>(stackTop_);
  142|   367k|    }
_ZN9rapidjson8internal5StackINS_12CrtAllocatorEE7DestroyEv:
  208|  17.4k|    void Destroy() {
  209|  17.4k|        Allocator::Free(stack_);
  210|  17.4k|        RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack
  ------------------
  |  |  716|  17.4k|#define RAPIDJSON_DELETE(x) delete x
  ------------------
  211|  17.4k|    }
_ZN9rapidjson8internal5StackINS_12CrtAllocatorEEC2EPS2_m:
   41|  17.4k|    Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) {
   42|  17.4k|    }
_ZN9rapidjson8internal5StackINS_12CrtAllocatorEED2Ev:
   62|  17.4k|    ~Stack() {
   63|  17.4k|        Destroy();
   64|  17.4k|    }

_ZN9rapidjson8internal6StrLenIcEEjPKT_:
   39|   356k|inline SizeType StrLen(const char* s) {
   40|   356k|    return SizeType(std::strlen(s));
   41|   356k|}

_ZN9rapidjson8internal8FastPathEdi:
   28|   469k|inline double FastPath(double significand, int exp) {
   29|   469k|    if (exp < -308)
  ------------------
  |  Branch (29:9): [True: 585, False: 469k]
  ------------------
   30|    585|        return 0.0;
   31|   469k|    else if (exp >= 0)
  ------------------
  |  Branch (31:14): [True: 7.30k, False: 461k]
  ------------------
   32|  7.30k|        return significand * internal::Pow10(exp);
   33|   461k|    else
   34|   461k|        return significand / internal::Pow10(-exp);
   35|   469k|}
_ZN9rapidjson8internal21StrtodNormalPrecisionEdi:
   37|   468k|inline double StrtodNormalPrecision(double d, int p) {
   38|   468k|    if (p < -308) {
  ------------------
  |  Branch (38:9): [True: 832, False: 468k]
  ------------------
   39|       |        // Prevent expSum < -308, making Pow10(p) = 0
   40|    832|        d = FastPath(d, -308);
   41|    832|        d = FastPath(d, p + 308);
   42|    832|    }
   43|   468k|    else
   44|   468k|        d = FastPath(d, p);
   45|   468k|    return d;
   46|   468k|}

_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE5ParseILj1ENS_25GenericInsituStringStreamIS2_EENS_15GenericDocumentIS2_NS_19MemoryPoolAllocatorIS3_EES3_EEEENS_11ParseResultERT0_RT1_:
  559|  8.71k|    ParseResult Parse(InputStream& is, Handler& handler) {
  560|  8.71k|        if (parseFlags & kParseIterativeFlag)
  ------------------
  |  Branch (560:13): [Folded, False: 8.71k]
  ------------------
  561|      0|            return IterativeParse<parseFlags>(is, handler);
  562|       |
  563|  8.71k|        parseResult_.Clear();
  564|       |
  565|  8.71k|        ClearStackOnExit scope(*this);
  566|       |
  567|  8.71k|        SkipWhitespaceAndComments<parseFlags>(is);
  568|  8.71k|        RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
  ------------------
  |  |   61|  8.71k|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|  8.71k|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |   62|  8.71k|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  ------------------
  |  |  |  |  505|  8.71k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (505:31): [True: 0, False: 8.71k]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   63|  8.71k|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|  8.71k|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|  8.71k|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 8.71k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  569|       |
  570|  8.71k|        if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) {
  ------------------
  |  |  505|  8.71k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 24, False: 8.69k]
  |  |  ------------------
  ------------------
  571|     24|            RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell());
  ------------------
  |  |  101|     24|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     24|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  102|     24|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  ------------------
  |  |  |  |  437|     24|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  ------------------
  |  |  103|     24|    SetParseError(parseErrorCode, offset); \
  |  |  104|     24|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     24|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     24|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 24]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (571:13): [True: 24, False: 0]
  ------------------
  572|     24|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
  ------------------
  |  |   61|     48|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     24|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |   62|     48|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  ------------------
  |  |  |  |  505|     24|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (505:31): [True: 24, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   63|     48|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     24|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     24|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  573|     24|        }
  574|  8.69k|        else {
  575|  8.69k|            ParseValue<parseFlags>(is, handler);
  576|  8.69k|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
  ------------------
  |  |   61|  8.69k|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|  8.69k|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |   62|  8.69k|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  ------------------
  |  |  |  |  505|  8.69k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (505:31): [True: 2.57k, False: 6.12k]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   63|  8.69k|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|  8.69k|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|  8.69k|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 6.12k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  577|       |
  578|  6.12k|            if (!(parseFlags & kParseStopWhenDoneFlag)) {
  ------------------
  |  Branch (578:17): [True: 6.12k, Folded]
  ------------------
  579|  6.12k|                SkipWhitespaceAndComments<parseFlags>(is);
  580|  6.12k|                RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
  ------------------
  |  |   61|  6.12k|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|  6.12k|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |   62|  6.12k|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  ------------------
  |  |  |  |  505|  6.12k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (505:31): [True: 0, False: 6.12k]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   63|  6.12k|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|  6.12k|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|  6.12k|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 6.12k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  581|       |
  582|  6.12k|                if (RAPIDJSON_UNLIKELY(is.Peek() != '\0')) {
  ------------------
  |  |  505|  6.12k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 224, False: 5.89k]
  |  |  ------------------
  ------------------
  583|    224|                    RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell());
  ------------------
  |  |  101|    224|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|    224|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  102|    224|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  ------------------
  |  |  |  |  437|    224|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  ------------------
  |  |  103|    224|    SetParseError(parseErrorCode, offset); \
  |  |  104|    224|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|    224|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|    224|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 224]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (583:21): [True: 224, False: 0]
  ------------------
  584|    224|                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
  ------------------
  |  |   61|    448|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|    224|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |   62|    448|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  ------------------
  |  |  |  |  505|    224|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (505:31): [True: 224, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   63|    448|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|    224|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|    224|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  585|    224|                }
  586|  6.12k|            }
  587|  6.12k|        }
  588|       |
  589|  5.89k|        return parseResult_;
  590|  8.71k|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE11ParseStringILj1ENS_25GenericInsituStringStreamIS2_EENS_15GenericDocumentIS2_NS_19MemoryPoolAllocatorIS3_EES3_EEEEvRT0_RT1_b:
  959|  5.80M|    void ParseString(InputStream& is, Handler& handler, bool isKey = false) {
  960|  5.80M|        internal::StreamLocalCopy<InputStream> copy(is);
  961|  5.80M|        InputStream& s(copy.s);
  962|       |
  963|  5.80M|        RAPIDJSON_ASSERT(s.Peek() == '\"');
  ------------------
  |  |  437|  5.80M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (963:9): [True: 5.80M, False: 0]
  ------------------
  964|  5.80M|        s.Take();  // Skip '\"'
  965|       |
  966|  5.80M|        bool success = false;
  967|  5.80M|        if (parseFlags & kParseInsituFlag) {
  ------------------
  |  Branch (967:13): [True: 5.80M, Folded]
  ------------------
  968|  5.80M|            typename InputStream::Ch *head = s.PutBegin();
  969|  5.80M|            ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);
  970|  5.80M|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  5.80M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  5.80M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  5.80M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  5.80M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  5.80M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 194, False: 5.80M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  5.80M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  5.80M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  5.80M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 5.80M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  971|  5.80M|            size_t length = s.PutEnd(head) - 1;
  972|  5.80M|            RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
  ------------------
  |  |  437|  5.80M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (972:13): [True: 5.80M, False: 0]
  ------------------
  973|  5.80M|            const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
  974|  5.80M|            success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false));
  ------------------
  |  Branch (974:24): [True: 5.68M, False: 112k]
  ------------------
  975|  5.80M|        }
  976|      0|        else {
  977|      0|            StackStream<typename TargetEncoding::Ch> stackStream(stack_);
  978|      0|            ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);
  979|      0|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|      0|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  980|      0|            SizeType length = static_cast<SizeType>(stackStream.Length()) - 1;
  981|      0|            const typename TargetEncoding::Ch* const str = stackStream.Pop();
  982|      0|            success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true));
  ------------------
  |  Branch (982:24): [True: 0, False: 0]
  ------------------
  983|      0|        }
  984|  5.80M|        if (RAPIDJSON_UNLIKELY(!success))
  ------------------
  |  |  505|  5.80M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 5.80M]
  |  |  ------------------
  ------------------
  985|       |            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
  ------------------
  |  |  120|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      0|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      0|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      0|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      0|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (985:13): [True: 0, False: 0]
  ------------------
  986|  5.80M|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE19ParseStringToStreamILj1ES2_S2_NS_25GenericInsituStringStreamIS2_EES7_EEvRT2_RT3_:
  991|  5.80M|    RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) {
  992|       |//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
  993|  5.80M|#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  994|  5.80M|        static const char escape[256] = {
  995|  5.80M|            Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '/',
  ------------------
  |  |  993|  5.80M|#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  ------------------
                          Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '/',
  ------------------
  |  |  993|  5.80M|#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  ------------------
  996|  5.80M|            Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
  ------------------
  |  |  993|  5.80M|#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  ------------------
                          Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
  ------------------
  |  |  993|  5.80M|#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  ------------------
  997|  5.80M|            0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
  998|  5.80M|            0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  999|  5.80M|            Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
  ------------------
  |  |  993|  5.80M|#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  ------------------
                          Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
  ------------------
  |  |  993|  5.80M|#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  ------------------
                          Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
  ------------------
  |  |  993|  5.80M|#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  ------------------
                          Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
  ------------------
  |  |  993|  5.80M|#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  ------------------
                          Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
  ------------------
  |  |  993|  5.80M|#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  ------------------
                          Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
  ------------------
  |  |  993|  5.80M|#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  ------------------
                          Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
  ------------------
  |  |  993|  5.80M|#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  ------------------
                          Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
  ------------------
  |  |  993|  5.80M|#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  ------------------
 1000|  5.80M|        };
 1001|  5.80M|#undef Z16
 1002|       |//!@endcond
 1003|       |
 1004|  45.8M|        for (;;) {
 1005|       |            // Scan and copy string before "\\\"" or < 0x20. This is an optional optimzation.
 1006|  45.8M|            if (!(parseFlags & kParseValidateEncodingFlag))
  ------------------
  |  Branch (1006:17): [True: 45.8M, Folded]
  ------------------
 1007|  45.8M|                ScanCopyUnescapedString(is, os);
 1008|       |
 1009|  45.8M|            Ch c = is.Peek();
 1010|  45.8M|            if (RAPIDJSON_UNLIKELY(c == '\\')) {    // Escape
  ------------------
  |  |  505|  45.8M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 3.98k, False: 45.8M]
  |  |  ------------------
  ------------------
 1011|  3.98k|                size_t escapeOffset = is.Tell();    // For invalid escaping, report the initial '\\' as error offset
 1012|  3.98k|                is.Take();
 1013|  3.98k|                Ch e = is.Peek();
 1014|  3.98k|                if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) {
  ------------------
  |  |  492|  3.98k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 832, False: 3.15k]
  |  |  ------------------
  ------------------
  |  Branch (1014:22): [True: 3.98k, Folded]
  |  Branch (1014:41): [True: 0, False: 0]
  ------------------
 1015|    832|                    is.Take();
 1016|    832|                    os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
 1017|    832|                }
 1018|  3.15k|                else if ((parseFlags & kParseEscapedApostropheFlag) && RAPIDJSON_LIKELY(e == '\'')) { // Allow escaped apostrophe
  ------------------
  |  |  492|      0|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (1018:26): [Folded, False: 3.15k]
  ------------------
 1019|      0|                    is.Take();
 1020|      0|                    os.Put('\'');
 1021|      0|                }
 1022|  3.15k|                else if (RAPIDJSON_LIKELY(e == 'u')) {    // Unicode
  ------------------
  |  |  492|  3.15k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 3.14k, False: 14]
  |  |  ------------------
  ------------------
 1023|  3.14k|                    is.Take();
 1024|  3.14k|                    unsigned codepoint = ParseHex4(is, escapeOffset);
 1025|  3.14k|                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  3.14k|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  3.14k|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  3.14k|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  3.14k|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  3.14k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 28, False: 3.11k]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  3.14k|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  3.14k|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  3.14k|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 3.11k]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1026|  3.11k|                    if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDFFF)) {
  ------------------
  |  |  505|  3.85k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 498, False: 2.61k]
  |  |  |  Branch (505:51): [True: 735, False: 2.38k]
  |  |  |  Branch (505:51): [True: 498, False: 237]
  |  |  ------------------
  ------------------
 1027|       |                        // high surrogate, check if followed by valid low surrogate
 1028|    498|                        if (RAPIDJSON_LIKELY(codepoint <= 0xDBFF)) {
  ------------------
  |  |  492|    498|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 492, False: 6]
  |  |  ------------------
  ------------------
 1029|       |                            // Handle UTF-16 surrogate pair
 1030|    492|                            if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u')))
  ------------------
  |  |  505|    982|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 16, False: 476]
  |  |  |  Branch (505:51): [True: 2, False: 490]
  |  |  |  Branch (505:51): [True: 14, False: 476]
  |  |  ------------------
  ------------------
 1031|    492|                                RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
  ------------------
  |  |  120|     32|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     16|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|     32|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|     16|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|     16|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|     16|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|     16|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|     16|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|     16|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|     16|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|     16|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 16]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|     32|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|     16|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|     32|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|     16|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|     32|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|     16|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 16, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|     32|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|     16|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|     16|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|     16|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     16|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     16|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1031:33): [True: 16, False: 0]
  ------------------
 1032|    476|                            unsigned codepoint2 = ParseHex4(is, escapeOffset);
 1033|    476|                            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|    476|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|    476|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|    476|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|    476|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|    476|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 22, False: 454]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|    476|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|    476|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|    476|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 454]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1034|    454|                            if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF))
  ------------------
  |  |  505|    906|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 6, False: 448]
  |  |  |  Branch (505:51): [True: 2, False: 452]
  |  |  |  Branch (505:51): [True: 4, False: 448]
  |  |  ------------------
  ------------------
 1035|    454|                                RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
  ------------------
  |  |  120|     12|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      6|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|     12|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      6|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      6|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      6|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      6|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      6|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      6|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      6|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      6|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 6]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|     12|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      6|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|     12|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      6|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|     12|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      6|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 6, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|     12|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      6|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      6|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      6|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      6|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      6|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1035:33): [True: 6, False: 0]
  ------------------
 1036|    448|                            codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
 1037|    448|                        }
 1038|       |                        // single low surrogate
 1039|      6|                        else
 1040|      6|                        {
 1041|      6|                            RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
  ------------------
  |  |  120|      6|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      6|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      6|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      6|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      6|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      6|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      6|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      6|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      6|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      6|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      6|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 6]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      6|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      6|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|     12|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      6|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|     12|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      6|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 6, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|     12|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      6|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      6|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      6|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      6|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      6|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1041:29): [True: 6, False: 0]
  ------------------
 1042|      6|                        }
 1043|    498|                    }
 1044|  3.06k|                    TEncoding::Encode(os, codepoint);
 1045|  3.06k|                }
 1046|     14|                else
 1047|  3.15k|                    RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, escapeOffset);
  ------------------
  |  |  120|     28|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     14|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|     28|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|     14|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|     14|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|     14|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|     14|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|     14|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|     14|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|     14|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|     14|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 14]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|     28|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|     14|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|     28|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|     14|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|     28|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|     14|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 14, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|     28|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|     14|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|     14|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|     14|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     14|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     14|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1047:21): [True: 14, False: 0]
  ------------------
 1048|  3.98k|            }
 1049|  45.8M|            else if (RAPIDJSON_UNLIKELY(c == '"')) {    // Closing double quote
  ------------------
  |  |  505|  45.8M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 5.80M, False: 40.0M]
  |  |  ------------------
  ------------------
 1050|  5.80M|                is.Take();
 1051|  5.80M|                os.Put('\0');   // null-terminate the string
 1052|  5.80M|                return;
 1053|  5.80M|            }
 1054|  40.0M|            else if (RAPIDJSON_UNLIKELY(static_cast<unsigned>(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
  ------------------
  |  |  505|  40.0M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 102, False: 40.0M]
  |  |  ------------------
  ------------------
 1055|    102|                if (c == '\0')
  ------------------
  |  Branch (1055:21): [True: 86, False: 16]
  ------------------
 1056|    102|                    RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell());
  ------------------
  |  |  120|    172|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     86|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|    172|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|     86|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|     86|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|     86|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|     86|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|     86|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|     86|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|     86|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|     86|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 86]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|    172|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|     86|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|    172|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|     86|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|    172|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|     86|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 86, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|    172|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|     86|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|     86|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|     86|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     86|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     86|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1056:21): [True: 86, False: 0]
  ------------------
 1057|     16|                else
 1058|    102|                    RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, is.Tell());
  ------------------
  |  |  120|     32|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     16|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|     32|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|     16|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|     16|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|     16|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|     16|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|     16|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|     16|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|     16|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|     16|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 16]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|     32|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|     16|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|     32|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|     16|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|     32|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|     16|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 16, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|     32|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|     16|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|     16|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|     16|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     16|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     16|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1058:21): [True: 16, False: 0]
  ------------------
 1059|    102|            }
 1060|  40.0M|            else {
 1061|  40.0M|                size_t offset = is.Tell();
 1062|  40.0M|                if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ?
  ------------------
  |  |  505|  80.0M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 40.0M]
  |  |  |  Branch (505:51): [Folded, False: 40.0M]
  |  |  ------------------
  ------------------
 1063|  40.0M|                    !Transcoder<SEncoding, TEncoding>::Validate(is, os) :
 1064|  40.0M|                    !Transcoder<SEncoding, TEncoding>::Transcode(is, os))))
 1065|       |                    RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, offset);
  ------------------
  |  |  120|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      0|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      0|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      0|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      0|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1065:21): [True: 0, False: 0]
  ------------------
 1066|  40.0M|            }
 1067|  45.8M|        }
 1068|  5.80M|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE23ScanCopyUnescapedStringINS_25GenericInsituStringStreamIS2_EES7_EEvRT_RT0_:
 1071|  45.8M|    static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) {
 1072|       |            // Do nothing for generic version
 1073|  45.8M|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE9ParseHex4INS_25GenericInsituStringStreamIS2_EEEEjRT_m:
  906|  3.61k|    unsigned ParseHex4(InputStream& is, size_t escapeOffset) {
  907|  3.61k|        unsigned codepoint = 0;
  908|  17.9k|        for (int i = 0; i < 4; i++) {
  ------------------
  |  Branch (908:25): [True: 14.3k, False: 3.56k]
  ------------------
  909|  14.3k|            Ch c = is.Peek();
  910|  14.3k|            codepoint <<= 4;
  911|  14.3k|            codepoint += static_cast<unsigned>(c);
  912|  14.3k|            if (c >= '0' && c <= '9')
  ------------------
  |  Branch (912:17): [True: 14.3k, False: 34]
  |  Branch (912:29): [True: 7.42k, False: 6.93k]
  ------------------
  913|  7.42k|                codepoint -= '0';
  914|  6.97k|            else if (c >= 'A' && c <= 'F')
  ------------------
  |  Branch (914:22): [True: 6.93k, False: 34]
  |  Branch (914:34): [True: 2.39k, False: 4.54k]
  ------------------
  915|  2.39k|                codepoint -= 'A' - 10;
  916|  4.58k|            else if (c >= 'a' && c <= 'f')
  ------------------
  |  Branch (916:22): [True: 4.54k, False: 38]
  |  Branch (916:34): [True: 4.53k, False: 12]
  ------------------
  917|  4.53k|                codepoint -= 'a' - 10;
  918|     50|            else {
  919|     50|                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, escapeOffset);
  ------------------
  |  |  101|     50|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     50|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  102|     50|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  ------------------
  |  |  |  |  437|     50|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  ------------------
  |  |  103|     50|    SetParseError(parseErrorCode, offset); \
  |  |  104|     50|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     50|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     50|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 50]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (919:17): [True: 50, False: 0]
  ------------------
  920|     50|                RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0);
  ------------------
  |  |   61|    100|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     50|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |   62|    100|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  ------------------
  |  |  |  |  505|     50|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (505:31): [True: 50, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   63|    100|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     50|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     50|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  921|     50|            }
  922|  14.3k|            is.Take();
  923|  14.3k|        }
  924|  3.56k|        return codepoint;
  925|  3.61k|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE7ConsumeINS_25GenericInsituStringStreamIS2_EEEEbRT_NS8_2ChE:
  895|  41.0M|    RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) {
  896|  41.0M|        if (RAPIDJSON_LIKELY(is.Peek() == expect)) {
  ------------------
  |  |  492|  41.0M|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 33.6M, False: 7.40M]
  |  |  ------------------
  ------------------
  897|  33.6M|            is.Take();
  898|  33.6M|            return true;
  899|  33.6M|        }
  900|  7.40M|        else
  901|  7.40M|            return false;
  902|  41.0M|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE10ClearStackEv:
  698|  8.71k|    void ClearStack() { stack_.Clear(); }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE25SkipWhitespaceAndCommentsILj1ENS_25GenericInsituStringStreamIS2_EEEEvRT0_:
  711|  80.9M|    void SkipWhitespaceAndComments(InputStream& is) {
  712|  80.9M|        SkipWhitespace(is);
  713|       |
  714|  80.9M|        if (parseFlags & kParseCommentsFlag) {
  ------------------
  |  Branch (714:13): [Folded, False: 80.9M]
  ------------------
  715|      0|            while (RAPIDJSON_UNLIKELY(Consume(is, '/'))) {
  ------------------
  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  716|      0|                if (Consume(is, '*')) {
  ------------------
  |  Branch (716:21): [True: 0, False: 0]
  ------------------
  717|      0|                    while (true) {
  ------------------
  |  Branch (717:28): [True: 0, Folded]
  ------------------
  718|      0|                        if (RAPIDJSON_UNLIKELY(is.Peek() == '\0'))
  ------------------
  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  719|      0|                            RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
  ------------------
  |  |  120|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      0|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      0|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      0|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      0|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (719:29): [True: 0, False: 0]
  ------------------
  720|      0|                        else if (Consume(is, '*')) {
  ------------------
  |  Branch (720:34): [True: 0, False: 0]
  ------------------
  721|      0|                            if (Consume(is, '/'))
  ------------------
  |  Branch (721:33): [True: 0, False: 0]
  ------------------
  722|      0|                                break;
  723|      0|                        }
  724|      0|                        else
  725|      0|                            is.Take();
  726|      0|                    }
  727|      0|                }
  728|      0|                else if (RAPIDJSON_LIKELY(Consume(is, '/')))
  ------------------
  |  |  492|      0|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  729|      0|                    while (is.Peek() != '\0' && is.Take() != '\n') {}
  ------------------
  |  Branch (729:28): [True: 0, False: 0]
  |  Branch (729:49): [True: 0, False: 0]
  ------------------
  730|      0|                else
  731|      0|                    RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
  ------------------
  |  |  120|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      0|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      0|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      0|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      0|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (731:21): [True: 0, False: 0]
  ------------------
  732|       |
  733|      0|                SkipWhitespace(is);
  734|      0|            }
  735|      0|        }
  736|  80.9M|    }
_ZN9rapidjson14SkipWhitespaceINS_25GenericInsituStringStreamINS_4UTF8IcEEEEEEvRT_:
  266|  80.9M|void SkipWhitespace(InputStream& is) {
  267|  80.9M|    internal::StreamLocalCopy<InputStream> copy(is);
  268|  80.9M|    InputStream& s(copy.s);
  269|       |
  270|  80.9M|    typename InputStream::Ch c;
  271|  81.3M|    while ((c = s.Peek()) == ' ' || c == '\n' || c == '\r' || c == '\t')
  ------------------
  |  Branch (271:12): [True: 349k, False: 81.0M]
  |  Branch (271:37): [True: 15.3k, False: 81.0M]
  |  Branch (271:50): [True: 74.9k, False: 80.9M]
  |  Branch (271:63): [True: 3.21k, False: 80.9M]
  ------------------
  272|   443k|        s.Take();
  273|  80.9M|}
_ZNK9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE13HasParseErrorEv:
  682|   128M|    bool HasParseError() const { return parseResult_.IsError(); }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE13SetParseErrorENS_14ParseErrorCodeEm:
  691|  2.82k|    void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE10ParseValueILj1ENS_25GenericInsituStringStreamIS2_EENS_15GenericDocumentIS2_NS_19MemoryPoolAllocatorIS3_EES3_EEEEvRT0_RT1_:
 1752|  36.1M|    void ParseValue(InputStream& is, Handler& handler) {
 1753|  36.1M|        switch (is.Peek()) {
 1754|  5.76k|            case 'n': ParseNull  <parseFlags>(is, handler); break;
  ------------------
  |  Branch (1754:13): [True: 5.76k, False: 36.1M]
  ------------------
 1755|  23.9k|            case 't': ParseTrue  <parseFlags>(is, handler); break;
  ------------------
  |  Branch (1755:13): [True: 23.9k, False: 36.1M]
  ------------------
 1756|  32.7k|            case 'f': ParseFalse <parseFlags>(is, handler); break;
  ------------------
  |  Branch (1756:13): [True: 32.7k, False: 36.1M]
  ------------------
 1757|   112k|            case '"': ParseString<parseFlags>(is, handler); break;
  ------------------
  |  Branch (1757:13): [True: 112k, False: 36.0M]
  ------------------
 1758|  3.89M|            case '{': ParseObject<parseFlags>(is, handler); break;
  ------------------
  |  Branch (1758:13): [True: 3.89M, False: 32.2M]
  ------------------
 1759|  5.66M|            case '[': ParseArray <parseFlags>(is, handler); break;
  ------------------
  |  Branch (1759:13): [True: 5.66M, False: 30.5M]
  ------------------
 1760|  26.4M|            default :
  ------------------
  |  Branch (1760:13): [True: 26.4M, False: 9.73M]
  ------------------
 1761|  26.4M|                      ParseNumber<parseFlags>(is, handler);
 1762|  26.4M|                      break;
 1763|       |
 1764|  36.1M|        }
 1765|  36.1M|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE9ParseNullILj1ENS_25GenericInsituStringStreamIS2_EENS_15GenericDocumentIS2_NS_19MemoryPoolAllocatorIS3_EES3_EEEEvRT0_RT1_:
  856|  5.76k|    void ParseNull(InputStream& is, Handler& handler) {
  857|  5.76k|        RAPIDJSON_ASSERT(is.Peek() == 'n');
  ------------------
  |  |  437|  5.76k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (857:9): [True: 5.76k, False: 0]
  ------------------
  858|  5.76k|        is.Take();
  859|       |
  860|  5.76k|        if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) {
  ------------------
  |  |  492|  22.9k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 5.72k, False: 38]
  |  |  |  Branch (492:49): [True: 5.74k, False: 18]
  |  |  |  Branch (492:49): [True: 5.73k, False: 14]
  |  |  |  Branch (492:49): [True: 5.72k, False: 6]
  |  |  ------------------
  ------------------
  861|  5.72k|            if (RAPIDJSON_UNLIKELY(!handler.Null()))
  ------------------
  |  |  505|  5.72k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 5.72k]
  |  |  ------------------
  ------------------
  862|  5.72k|                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
  ------------------
  |  |  120|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      0|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      0|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      0|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      0|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (862:17): [True: 0, False: 0]
  ------------------
  863|  5.72k|        }
  864|     38|        else
  865|       |            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
  ------------------
  |  |  120|     76|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     38|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|     76|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|     38|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|     38|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|     38|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|     38|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|     38|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|     38|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|     38|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|     38|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 38]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|     76|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|     38|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|     76|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|     38|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|     76|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|     38|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 38, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|     76|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|     38|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|     38|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|     38|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     38|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     38|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (865:13): [True: 38, False: 0]
  ------------------
  866|  5.76k|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE9ParseTrueILj1ENS_25GenericInsituStringStreamIS2_EENS_15GenericDocumentIS2_NS_19MemoryPoolAllocatorIS3_EES3_EEEEvRT0_RT1_:
  869|  23.9k|    void ParseTrue(InputStream& is, Handler& handler) {
  870|  23.9k|        RAPIDJSON_ASSERT(is.Peek() == 't');
  ------------------
  |  |  437|  23.9k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (870:9): [True: 23.9k, False: 0]
  ------------------
  871|  23.9k|        is.Take();
  872|       |
  873|  23.9k|        if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) {
  ------------------
  |  |  492|  95.7k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 23.9k, False: 62]
  |  |  |  Branch (492:49): [True: 23.9k, False: 22]
  |  |  |  Branch (492:49): [True: 23.9k, False: 18]
  |  |  |  Branch (492:49): [True: 23.9k, False: 22]
  |  |  ------------------
  ------------------
  874|  23.9k|            if (RAPIDJSON_UNLIKELY(!handler.Bool(true)))
  ------------------
  |  |  505|  23.9k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 23.9k]
  |  |  ------------------
  ------------------
  875|  23.9k|                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
  ------------------
  |  |  120|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      0|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      0|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      0|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      0|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (875:17): [True: 0, False: 0]
  ------------------
  876|  23.9k|        }
  877|     62|        else
  878|       |            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
  ------------------
  |  |  120|    124|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     62|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|    124|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|     62|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|     62|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|     62|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|     62|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|     62|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|     62|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|     62|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|     62|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 62]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|    124|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|     62|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|    124|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|     62|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|    124|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|     62|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 62, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|    124|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|     62|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|     62|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|     62|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     62|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     62|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (878:13): [True: 62, False: 0]
  ------------------
  879|  23.9k|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE10ParseFalseILj1ENS_25GenericInsituStringStreamIS2_EENS_15GenericDocumentIS2_NS_19MemoryPoolAllocatorIS3_EES3_EEEEvRT0_RT1_:
  882|  32.7k|    void ParseFalse(InputStream& is, Handler& handler) {
  883|  32.7k|        RAPIDJSON_ASSERT(is.Peek() == 'f');
  ------------------
  |  |  437|  32.7k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (883:9): [True: 32.7k, False: 0]
  ------------------
  884|  32.7k|        is.Take();
  885|       |
  886|  32.7k|        if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) {
  ------------------
  |  |  492|   196k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 32.7k, False: 66]
  |  |  |  Branch (492:49): [True: 32.7k, False: 16]
  |  |  |  Branch (492:49): [True: 32.7k, False: 2]
  |  |  |  Branch (492:49): [True: 32.7k, False: 18]
  |  |  |  Branch (492:49): [True: 32.7k, False: 30]
  |  |  ------------------
  ------------------
  887|  32.7k|            if (RAPIDJSON_UNLIKELY(!handler.Bool(false)))
  ------------------
  |  |  505|  32.7k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 32.7k]
  |  |  ------------------
  ------------------
  888|  32.7k|                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
  ------------------
  |  |  120|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      0|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      0|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      0|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      0|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (888:17): [True: 0, False: 0]
  ------------------
  889|  32.7k|        }
  890|     66|        else
  891|       |            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
  ------------------
  |  |  120|    132|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     66|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|    132|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|     66|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|     66|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|     66|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|     66|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|     66|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|     66|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|     66|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|     66|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 66]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|    132|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|     66|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|    132|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|     66|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|    132|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|     66|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 66, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|    132|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|     66|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|     66|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|     66|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     66|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     66|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (891:13): [True: 66, False: 0]
  ------------------
  892|  32.7k|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE11ParseObjectILj1ENS_25GenericInsituStringStreamIS2_EENS_15GenericDocumentIS2_NS_19MemoryPoolAllocatorIS3_EES3_EEEEvRT0_RT1_:
  740|  3.89M|    void ParseObject(InputStream& is, Handler& handler) {
  741|  3.89M|        RAPIDJSON_ASSERT(is.Peek() == '{');
  ------------------
  |  |  437|  3.89M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (741:9): [True: 3.89M, False: 0]
  ------------------
  742|  3.89M|        is.Take();  // Skip '{'
  743|       |
  744|  3.89M|        if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
  ------------------
  |  |  505|  3.89M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 3.89M]
  |  |  ------------------
  ------------------
  745|  3.89M|            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
  ------------------
  |  |  120|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      0|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      0|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      0|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      0|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (745:13): [True: 0, False: 0]
  ------------------
  746|       |
  747|  3.89M|        SkipWhitespaceAndComments<parseFlags>(is);
  748|  3.89M|        RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  3.89M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  3.89M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  3.89M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  3.89M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  3.89M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 3.89M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  3.89M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  3.89M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  3.89M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 3.89M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  749|       |
  750|  3.89M|        if (Consume(is, '}')) {
  ------------------
  |  Branch (750:13): [True: 2.50M, False: 1.38M]
  ------------------
  751|  2.50M|            if (RAPIDJSON_UNLIKELY(!handler.EndObject(0)))  // empty object
  ------------------
  |  |  505|  2.50M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 2.50M]
  |  |  ------------------
  ------------------
  752|  2.50M|                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
  ------------------
  |  |  120|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      0|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      0|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      0|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      0|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (752:17): [True: 0, False: 0]
  ------------------
  753|  2.50M|            return;
  754|  2.50M|        }
  755|       |
  756|  5.68M|        for (SizeType memberCount = 0;;) {
  757|  5.68M|            if (RAPIDJSON_UNLIKELY(is.Peek() != '"'))
  ------------------
  |  |  505|  5.68M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 156, False: 5.68M]
  |  |  ------------------
  ------------------
  758|  5.68M|                RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell());
  ------------------
  |  |  120|    312|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|    156|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|    312|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|    156|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|    156|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|    156|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|    156|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|    156|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|    156|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|    156|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|    156|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 156]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|    312|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|    156|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|    312|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|    156|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|    312|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|    156|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 156, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|    312|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|    156|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|    156|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|    156|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|    156|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|    156|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (758:17): [True: 156, False: 0]
  ------------------
  759|       |
  760|  5.68M|            ParseString<parseFlags>(is, handler, true);
  761|  5.68M|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  5.68M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  5.68M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  5.68M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  5.68M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  5.68M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 30, False: 5.68M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  5.68M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  5.68M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  5.68M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 5.68M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  762|       |
  763|  5.68M|            SkipWhitespaceAndComments<parseFlags>(is);
  764|  5.68M|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  5.68M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  5.68M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  5.68M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  5.68M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  5.68M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 5.68M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  5.68M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  5.68M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  5.68M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 5.68M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  765|       |
  766|  5.68M|            if (RAPIDJSON_UNLIKELY(!Consume(is, ':')))
  ------------------
  |  |  505|  5.68M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 70, False: 5.68M]
  |  |  ------------------
  ------------------
  767|  5.68M|                RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());
  ------------------
  |  |  120|    140|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     70|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|    140|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|     70|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|     70|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|     70|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|     70|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|     70|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|     70|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|     70|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|     70|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 70]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|    140|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|     70|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|    140|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|     70|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|    140|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|     70|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 70, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|    140|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|     70|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|     70|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|     70|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     70|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     70|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (767:17): [True: 70, False: 0]
  ------------------
  768|       |
  769|  5.68M|            SkipWhitespaceAndComments<parseFlags>(is);
  770|  5.68M|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  5.68M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  5.68M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  5.68M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  5.68M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  5.68M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 5.68M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  5.68M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  5.68M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  5.68M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 5.68M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  771|       |
  772|  5.68M|            ParseValue<parseFlags>(is, handler);
  773|  5.68M|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  5.68M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  5.68M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  5.68M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  5.68M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  5.68M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 6.50k, False: 5.68M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  5.68M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  5.68M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  5.68M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 5.68M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  774|       |
  775|  5.68M|            SkipWhitespaceAndComments<parseFlags>(is);
  776|  5.68M|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  5.68M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  5.68M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  5.68M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  5.68M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  5.68M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 5.68M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  5.68M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  5.68M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  5.68M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 5.68M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  777|       |
  778|  5.68M|            ++memberCount;
  779|       |
  780|  5.68M|            switch (is.Peek()) {
  781|  4.30M|                case ',':
  ------------------
  |  Branch (781:17): [True: 4.30M, False: 1.37M]
  ------------------
  782|  4.30M|                    is.Take();
  783|  4.30M|                    SkipWhitespaceAndComments<parseFlags>(is);
  784|  4.30M|                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  4.30M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  4.30M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  4.30M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  4.30M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  4.30M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 4.30M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  4.30M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  4.30M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  4.30M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 4.30M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  785|  4.30M|                    break;
  786|  4.30M|                case '}':
  ------------------
  |  Branch (786:17): [True: 1.37M, False: 4.30M]
  ------------------
  787|  1.37M|                    is.Take();
  788|  1.37M|                    if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
  ------------------
  |  |  505|  1.37M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 1.37M]
  |  |  ------------------
  ------------------
  789|  1.37M|                        RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
  ------------------
  |  |  120|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      0|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      0|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      0|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      0|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (789:25): [True: 0, False: 0]
  ------------------
  790|  1.37M|                    return;
  791|  1.37M|                default:
  ------------------
  |  Branch (791:17): [True: 98, False: 5.68M]
  ------------------
  792|     98|                    RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy
  ------------------
  |  |  120|     98|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     98|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|     98|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|     98|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|     98|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|     98|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|     98|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|     98|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|     98|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|     98|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|     98|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 98]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|     98|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|     98|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|    196|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|     98|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|    196|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|     98|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 98, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|    196|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|     98|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|     98|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|     98|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     98|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     98|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (792:21): [True: 98, False: 0]
  ------------------
  793|  5.68M|            }
  794|       |
  795|  4.30M|            if (parseFlags & kParseTrailingCommasFlag) {
  ------------------
  |  Branch (795:17): [Folded, False: 4.30M]
  ------------------
  796|      0|                if (is.Peek() == '}') {
  ------------------
  |  Branch (796:21): [True: 0, False: 0]
  ------------------
  797|      0|                    if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
  ------------------
  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  798|      0|                        RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
  ------------------
  |  |  120|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      0|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      0|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      0|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      0|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (798:25): [True: 0, False: 0]
  ------------------
  799|      0|                    is.Take();
  800|      0|                    return;
  801|      0|                }
  802|      0|            }
  803|  4.30M|        }
  804|  1.38M|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE10ParseArrayILj1ENS_25GenericInsituStringStreamIS2_EENS_15GenericDocumentIS2_NS_19MemoryPoolAllocatorIS3_EES3_EEEEvRT0_RT1_:
  808|  5.66M|    void ParseArray(InputStream& is, Handler& handler) {
  809|  5.66M|        RAPIDJSON_ASSERT(is.Peek() == '[');
  ------------------
  |  |  437|  5.66M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (809:9): [True: 5.66M, False: 0]
  ------------------
  810|  5.66M|        is.Take();  // Skip '['
  811|       |
  812|  5.66M|        if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
  ------------------
  |  |  505|  5.66M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 5.66M]
  |  |  ------------------
  ------------------
  813|  5.66M|            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
  ------------------
  |  |  120|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      0|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      0|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      0|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      0|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (813:13): [True: 0, False: 0]
  ------------------
  814|       |
  815|  5.66M|        SkipWhitespaceAndComments<parseFlags>(is);
  816|  5.66M|        RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  5.66M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  5.66M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  5.66M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  5.66M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  5.66M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 5.66M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  5.66M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  5.66M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  5.66M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 5.66M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  817|       |
  818|  5.66M|        if (Consume(is, ']')) {
  ------------------
  |  Branch (818:13): [True: 3.85k, False: 5.66M]
  ------------------
  819|  3.85k|            if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array
  ------------------
  |  |  505|  3.85k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 3.85k]
  |  |  ------------------
  ------------------
  820|  3.85k|                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
  ------------------
  |  |  120|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      0|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      0|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      0|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      0|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (820:17): [True: 0, False: 0]
  ------------------
  821|  3.85k|            return;
  822|  3.85k|        }
  823|       |
  824|  30.4M|        for (SizeType elementCount = 0;;) {
  825|  30.4M|            ParseValue<parseFlags>(is, handler);
  826|  30.4M|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  30.4M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  30.4M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  30.4M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  30.4M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  30.4M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 5.30M, False: 25.1M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  30.4M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  30.4M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  30.4M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 25.1M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  827|       |
  828|  25.1M|            ++elementCount;
  829|  25.1M|            SkipWhitespaceAndComments<parseFlags>(is);
  830|  25.1M|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  25.1M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  25.1M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  25.1M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  25.1M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  25.1M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 25.1M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  25.1M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  25.1M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  25.1M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 25.1M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  831|       |
  832|  25.1M|            if (Consume(is, ',')) {
  ------------------
  |  Branch (832:17): [True: 24.8M, False: 358k]
  ------------------
  833|  24.8M|                SkipWhitespaceAndComments<parseFlags>(is);
  834|  24.8M|                RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  24.8M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  24.8M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  24.8M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  24.8M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  24.8M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 24.8M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  24.8M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  24.8M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  24.8M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 24.8M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  835|  24.8M|            }
  836|   358k|            else if (Consume(is, ']')) {
  ------------------
  |  Branch (836:22): [True: 357k, False: 938]
  ------------------
  837|   357k|                if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
  ------------------
  |  |  505|   357k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 357k]
  |  |  ------------------
  ------------------
  838|   357k|                    RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
  ------------------
  |  |  120|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      0|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      0|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      0|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      0|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (838:21): [True: 0, False: 0]
  ------------------
  839|   357k|                return;
  840|   357k|            }
  841|    938|            else
  842|   358k|                RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
  ------------------
  |  |  120|  1.87k|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|    938|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|  1.87k|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|    938|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|    938|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|    938|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|    938|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|    938|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|    938|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|    938|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|    938|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 938]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|  1.87k|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|    938|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|  1.87k|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|    938|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|  1.87k|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|    938|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 938, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|  1.87k|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|    938|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|    938|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|    938|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|    938|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|    938|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (842:17): [True: 938, False: 0]
  ------------------
  843|       |
  844|  24.8M|            if (parseFlags & kParseTrailingCommasFlag) {
  ------------------
  |  Branch (844:17): [Folded, False: 24.8M]
  ------------------
  845|      0|                if (is.Peek() == ']') {
  ------------------
  |  Branch (845:21): [True: 0, False: 0]
  ------------------
  846|      0|                    if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
  ------------------
  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  847|      0|                        RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
  ------------------
  |  |  120|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      0|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      0|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      0|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      0|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (847:25): [True: 0, False: 0]
  ------------------
  848|      0|                    is.Take();
  849|      0|                    return;
  850|      0|                }
  851|      0|            }
  852|  24.8M|        }
  853|  5.66M|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE11ParseNumberILj1ENS_25GenericInsituStringStreamIS2_EENS_15GenericDocumentIS2_NS_19MemoryPoolAllocatorIS3_EES3_EEEEvRT0_RT1_:
 1468|  26.4M|    void ParseNumber(InputStream& is, Handler& handler) {
 1469|  26.4M|        typedef typename internal::SelectIf<internal::BoolType<(parseFlags & kParseNumbersAsStringsFlag) != 0>, typename TargetEncoding::Ch, char>::Type NumberCharacter;
 1470|       |
 1471|  26.4M|        internal::StreamLocalCopy<InputStream> copy(is);
 1472|  26.4M|        NumberStream<InputStream, NumberCharacter,
 1473|  26.4M|            ((parseFlags & kParseNumbersAsStringsFlag) != 0) ?
 1474|  26.4M|                ((parseFlags & kParseInsituFlag) == 0) :
 1475|  26.4M|                ((parseFlags & kParseFullPrecisionFlag) != 0),
 1476|  26.4M|            (parseFlags & kParseNumbersAsStringsFlag) != 0 &&
 1477|  26.4M|                (parseFlags & kParseInsituFlag) == 0> s(*this, copy.s);
 1478|       |
 1479|  26.4M|        size_t startOffset = s.Tell();
 1480|  26.4M|        double d = 0.0;
 1481|  26.4M|        bool useNanOrInf = false;
 1482|       |
 1483|       |        // Parse minus
 1484|  26.4M|        bool minus = Consume(s, '-');
 1485|       |
 1486|       |        // Parse int: zero / ( digit1-9 *DIGIT )
 1487|  26.4M|        unsigned i = 0;
 1488|  26.4M|        uint64_t i64 = 0;
 1489|  26.4M|        bool use64bit = false;
 1490|  26.4M|        int significandDigit = 0;
 1491|  26.4M|        if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) {
  ------------------
  |  |  505|  26.4M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 2.75M, False: 23.7M]
  |  |  ------------------
  ------------------
 1492|  2.75M|            i = 0;
 1493|  2.75M|            s.TakePush();
 1494|  2.75M|        }
 1495|  23.7M|        else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) {
  ------------------
  |  |  492|  47.4M|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 23.7M, False: 904]
  |  |  |  Branch (492:49): [True: 23.7M, False: 766]
  |  |  |  Branch (492:49): [True: 23.7M, False: 138]
  |  |  ------------------
  ------------------
 1496|  23.7M|            i = static_cast<unsigned>(s.TakePush() - '0');
 1497|       |
 1498|  23.7M|            if (minus)
  ------------------
  |  Branch (1498:17): [True: 273k, False: 23.4M]
  ------------------
 1499|  1.34M|                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|  2.49M|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 1.13M, False: 212k]
  |  |  |  Branch (492:49): [True: 1.14M, False: 206k]
  |  |  |  Branch (492:49): [True: 1.13M, False: 5.42k]
  |  |  ------------------
  ------------------
 1500|  1.13M|                    if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648
  ------------------
  |  |  505|  1.13M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 117k, False: 1.01M]
  |  |  ------------------
  ------------------
 1501|   117k|                        if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) {
  ------------------
  |  |  492|   230k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 60.8k, False: 56.6k]
  |  |  |  Branch (492:49): [True: 4.40k, False: 113k]
  |  |  |  Branch (492:49): [True: 56.4k, False: 56.6k]
  |  |  ------------------
  ------------------
 1502|  60.8k|                            i64 = i;
 1503|  60.8k|                            use64bit = true;
 1504|  60.8k|                            break;
 1505|  60.8k|                        }
 1506|   117k|                    }
 1507|  1.07M|                    i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
 1508|  1.07M|                    significandDigit++;
 1509|  1.07M|                }
 1510|  23.4M|            else
 1511|  24.2M|                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|  26.4M|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 881k, False: 23.4M]
  |  |  |  Branch (492:49): [True: 2.19M, False: 22.0M]
  |  |  |  Branch (492:49): [True: 881k, False: 1.31M]
  |  |  ------------------
  ------------------
 1512|   881k|                    if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295
  ------------------
  |  |  505|   881k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 21.6k, False: 859k]
  |  |  ------------------
  ------------------
 1513|  21.6k|                        if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) {
  ------------------
  |  |  492|  28.3k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 19.0k, False: 2.53k]
  |  |  |  Branch (492:49): [True: 14.8k, False: 6.76k]
  |  |  |  Branch (492:49): [True: 4.23k, False: 2.53k]
  |  |  ------------------
  ------------------
 1514|  19.0k|                            i64 = i;
 1515|  19.0k|                            use64bit = true;
 1516|  19.0k|                            break;
 1517|  19.0k|                        }
 1518|  21.6k|                    }
 1519|   862k|                    i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
 1520|   862k|                    significandDigit++;
 1521|   862k|                }
 1522|  23.7M|        }
 1523|       |        // Parse NaN or Infinity here
 1524|    904|        else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) {
  ------------------
  |  |  492|      0|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 0, False: 0]
  |  |  |  Branch (492:49): [True: 0, False: 0]
  |  |  |  Branch (492:49): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (1524:18): [Folded, False: 904]
  ------------------
 1525|      0|            if (Consume(s, 'N')) {
  ------------------
  |  Branch (1525:17): [True: 0, False: 0]
  ------------------
 1526|      0|                if (Consume(s, 'a') && Consume(s, 'N')) {
  ------------------
  |  Branch (1526:21): [True: 0, False: 0]
  |  Branch (1526:40): [True: 0, False: 0]
  ------------------
 1527|      0|                    d = std::numeric_limits<double>::quiet_NaN();
 1528|      0|                    useNanOrInf = true;
 1529|      0|                }
 1530|      0|            }
 1531|      0|            else if (RAPIDJSON_LIKELY(Consume(s, 'I'))) {
  ------------------
  |  |  492|      0|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1532|      0|                if (Consume(s, 'n') && Consume(s, 'f')) {
  ------------------
  |  Branch (1532:21): [True: 0, False: 0]
  |  Branch (1532:40): [True: 0, False: 0]
  ------------------
 1533|      0|                    d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity());
  ------------------
  |  Branch (1533:26): [True: 0, False: 0]
  ------------------
 1534|      0|                    useNanOrInf = true;
 1535|       |
 1536|      0|                    if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n')
  ------------------
  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  Branch (505:51): [True: 0, False: 0]
  |  |  |  Branch (505:51): [True: 0, False: 0]
  |  |  |  Branch (505:51): [True: 0, False: 0]
  |  |  |  Branch (505:51): [True: 0, False: 0]
  |  |  |  Branch (505:51): [True: 0, False: 0]
  |  |  |  Branch (505:51): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1537|      0|                                                                && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y')))) {
 1538|      0|                        RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
  ------------------
  |  |  120|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      0|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      0|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      0|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      0|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1538:25): [True: 0, False: 0]
  ------------------
 1539|      0|                    }
 1540|      0|                }
 1541|      0|            }
 1542|       |
 1543|      0|            if (RAPIDJSON_UNLIKELY(!useNanOrInf)) {
  ------------------
  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1544|      0|                RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
  ------------------
  |  |  120|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      0|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      0|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      0|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      0|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1544:17): [True: 0, False: 0]
  ------------------
 1545|      0|            }
 1546|      0|        }
 1547|    904|        else
 1548|    904|            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
  ------------------
  |  |  120|  1.80k|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|    904|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|  1.80k|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|    904|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|    904|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|    904|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|    904|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|    904|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|    904|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|    904|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|    904|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 904]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|  1.80k|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|    904|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|  1.80k|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|    904|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|  1.80k|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|    904|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 904, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|  1.80k|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|    904|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|    904|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|    904|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|    904|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|    904|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1548:13): [True: 904, False: 0]
  ------------------
 1549|       |
 1550|       |        // Parse 64bit int
 1551|  26.4M|        bool useDouble = false;
 1552|  26.4M|        if (use64bit) {
  ------------------
  |  Branch (1552:13): [True: 79.8k, False: 26.3M]
  ------------------
 1553|  79.8k|            if (minus)
  ------------------
  |  Branch (1553:17): [True: 60.8k, False: 19.0k]
  ------------------
 1554|   137k|                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|   214k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 77.1k, False: 59.9k]
  |  |  |  Branch (492:49): [True: 77.2k, False: 59.7k]
  |  |  |  Branch (492:49): [True: 77.1k, False: 127]
  |  |  ------------------
  ------------------
 1555|  77.1k|                     if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808
  ------------------
  |  |  505|  77.1k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 1.22k, False: 75.9k]
  |  |  ------------------
  ------------------
 1556|  1.22k|                        if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) {
  ------------------
  |  |  492|  1.88k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 894, False: 329]
  |  |  |  Branch (492:49): [True: 566, False: 657]
  |  |  |  Branch (492:49): [True: 328, False: 329]
  |  |  ------------------
  ------------------
 1557|    894|                            d = static_cast<double>(i64);
 1558|    894|                            useDouble = true;
 1559|    894|                            break;
 1560|    894|                        }
 1561|  76.2k|                    i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
 1562|  76.2k|                    significandDigit++;
 1563|  76.2k|                }
 1564|  19.0k|            else
 1565|   129k|                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|   244k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 113k, False: 15.7k]
  |  |  |  Branch (492:49): [True: 115k, False: 13.7k]
  |  |  |  Branch (492:49): [True: 113k, False: 2.07k]
  |  |  ------------------
  ------------------
 1566|   113k|                    if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615
  ------------------
  |  |  505|   113k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 4.73k, False: 108k]
  |  |  ------------------
  ------------------
 1567|  4.73k|                        if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) {
  ------------------
  |  |  492|  6.65k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 3.29k, False: 1.44k]
  |  |  |  Branch (492:49): [True: 2.81k, False: 1.91k]
  |  |  |  Branch (492:49): [True: 472, False: 1.44k]
  |  |  ------------------
  ------------------
 1568|  3.29k|                            d = static_cast<double>(i64);
 1569|  3.29k|                            useDouble = true;
 1570|  3.29k|                            break;
 1571|  3.29k|                        }
 1572|   110k|                    i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
 1573|   110k|                    significandDigit++;
 1574|   110k|                }
 1575|  79.8k|        }
 1576|       |
 1577|       |        // Force double for big integer
 1578|  26.4M|        if (useDouble) {
  ------------------
  |  Branch (1578:13): [True: 4.18k, False: 26.4M]
  ------------------
 1579|  46.2k|            while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|  89.0k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 42.0k, False: 4.18k]
  |  |  |  Branch (492:49): [True: 42.8k, False: 3.35k]
  |  |  |  Branch (492:49): [True: 42.0k, False: 826]
  |  |  ------------------
  ------------------
 1580|  42.0k|                d = d * 10 + (s.TakePush() - '0');
 1581|  42.0k|            }
 1582|  4.18k|        }
 1583|       |
 1584|       |        // Parse frac = decimal-point 1*DIGIT
 1585|  26.4M|        int expFrac = 0;
 1586|  26.4M|        size_t decimalPosition;
 1587|  26.4M|        if (Consume(s, '.')) {
  ------------------
  |  Branch (1587:13): [True: 460k, False: 25.9M]
  ------------------
 1588|   460k|            decimalPosition = s.Length();
 1589|       |
 1590|   460k|            if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9')))
  ------------------
  |  |  505|   920k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 12, False: 460k]
  |  |  |  Branch (505:51): [True: 460k, False: 6]
  |  |  |  Branch (505:51): [True: 460k, False: 6]
  |  |  ------------------
  ------------------
 1591|   460k|                RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell());
  ------------------
  |  |  120|     24|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     12|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|     24|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|     12|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|     12|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|     12|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|     12|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|     12|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|     12|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|     12|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|     12|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 12]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|     24|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|     12|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|     24|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|     12|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|     24|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|     12|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 12, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|     24|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|     12|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|     12|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|     12|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     12|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     12|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1591:17): [True: 12, False: 0]
  ------------------
 1592|       |
 1593|   460k|            if (!useDouble) {
  ------------------
  |  Branch (1593:17): [True: 460k, False: 228]
  ------------------
 1594|   460k|#if RAPIDJSON_64BIT
 1595|       |                // Use i64 to store significand in 64-bit architecture
 1596|   460k|                if (!use64bit)
  ------------------
  |  Branch (1596:21): [True: 459k, False: 708]
  ------------------
 1597|   459k|                    i64 = i;
 1598|       |
 1599|  2.46M|                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|  4.60M|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 2.01M, False: 458k]
  |  |  |  Branch (492:49): [True: 2.13M, False: 338k]
  |  |  |  Branch (492:49): [True: 2.01M, False: 119k]
  |  |  ------------------
  ------------------
 1600|  2.01M|                    if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path
  ------------------
  |  |  320|  2.01M|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  ------------------
  |  Branch (1600:25): [True: 1.66k, False: 2.00M]
  ------------------
 1601|  1.66k|                        break;
 1602|  2.00M|                    else {
 1603|  2.00M|                        i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
 1604|  2.00M|                        --expFrac;
 1605|  2.00M|                        if (i64 != 0)
  ------------------
  |  Branch (1605:29): [True: 1.64M, False: 365k]
  ------------------
 1606|  1.64M|                            significandDigit++;
 1607|  2.00M|                    }
 1608|  2.01M|                }
 1609|       |
 1610|   460k|                d = static_cast<double>(i64);
 1611|       |#else
 1612|       |                // Use double to store significand in 32-bit architecture
 1613|       |                d = static_cast<double>(use64bit ? i64 : i);
 1614|       |#endif
 1615|   460k|                useDouble = true;
 1616|   460k|            }
 1617|       |
 1618|   538k|            while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|   738k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 78.6k, False: 460k]
  |  |  |  Branch (492:49): [True: 199k, False: 339k]
  |  |  |  Branch (492:49): [True: 78.6k, False: 120k]
  |  |  ------------------
  ------------------
 1619|  78.6k|                if (significandDigit < 17) {
  ------------------
  |  Branch (1619:21): [True: 1.30k, False: 77.3k]
  ------------------
 1620|  1.30k|                    d = d * 10.0 + (s.TakePush() - '0');
 1621|  1.30k|                    --expFrac;
 1622|  1.30k|                    if (RAPIDJSON_LIKELY(d > 0.0))
  ------------------
  |  |  492|  1.30k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 1.30k, False: 0]
  |  |  ------------------
  ------------------
 1623|  1.30k|                        significandDigit++;
 1624|  1.30k|                }
 1625|  77.3k|                else
 1626|  77.3k|                    s.TakePush();
 1627|  78.6k|            }
 1628|   460k|        }
 1629|  25.9M|        else
 1630|  25.9M|            decimalPosition = s.Length(); // decimal position at the end of integer.
 1631|       |
 1632|       |        // Parse exp = e [ minus / plus ] 1*DIGIT
 1633|  26.4M|        int exp = 0;
 1634|  26.4M|        if (Consume(s, 'e') || Consume(s, 'E')) {
  ------------------
  |  Branch (1634:13): [True: 59.8k, False: 26.3M]
  |  Branch (1634:32): [True: 1.74k, False: 26.3M]
  ------------------
 1635|  61.6k|            if (!useDouble) {
  ------------------
  |  Branch (1635:17): [True: 4.73k, False: 56.9k]
  ------------------
 1636|  4.73k|                d = static_cast<double>(use64bit ? i64 : i);
  ------------------
  |  Branch (1636:41): [True: 128, False: 4.60k]
  ------------------
 1637|  4.73k|                useDouble = true;
 1638|  4.73k|            }
 1639|       |
 1640|  61.6k|            bool expMinus = false;
 1641|  61.6k|            if (Consume(s, '+'))
  ------------------
  |  Branch (1641:17): [True: 278, False: 61.3k]
  ------------------
 1642|    278|                ;
 1643|  61.3k|            else if (Consume(s, '-'))
  ------------------
  |  Branch (1643:22): [True: 58.7k, False: 2.57k]
  ------------------
 1644|  58.7k|                expMinus = true;
 1645|       |
 1646|  61.6k|            if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|   123k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 61.6k, False: 30]
  |  |  |  Branch (492:49): [True: 61.6k, False: 26]
  |  |  |  Branch (492:49): [True: 61.6k, False: 4]
  |  |  ------------------
  ------------------
 1647|  61.6k|                exp = static_cast<int>(s.Take() - '0');
 1648|  61.6k|                if (expMinus) {
  ------------------
  |  Branch (1648:21): [True: 58.7k, False: 2.82k]
  ------------------
 1649|       |                    // (exp + expFrac) must not underflow int => we're detecting when -exp gets
 1650|       |                    // dangerously close to INT_MIN (a pessimistic next digit 9 would push it into
 1651|       |                    // underflow territory):
 1652|       |                    //
 1653|       |                    //        -(exp * 10 + 9) + expFrac >= INT_MIN
 1654|       |                    //   <=>  exp <= (expFrac - INT_MIN - 9) / 10
 1655|  58.7k|                    RAPIDJSON_ASSERT(expFrac <= 0);
  ------------------
  |  |  437|  58.7k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1655:21): [True: 58.7k, False: 0]
  ------------------
 1656|  58.7k|                    int maxExp = (expFrac + 2147483639) / 10;
 1657|       |
 1658|  76.7k|                    while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|  96.4k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 17.9k, False: 58.7k]
  |  |  |  Branch (492:49): [True: 19.6k, False: 57.0k]
  |  |  |  Branch (492:49): [True: 17.9k, False: 1.70k]
  |  |  ------------------
  ------------------
 1659|  17.9k|                        exp = exp * 10 + static_cast<int>(s.Take() - '0');
 1660|  17.9k|                        if (RAPIDJSON_UNLIKELY(exp > maxExp)) {
  ------------------
  |  |  505|  17.9k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 280, False: 17.6k]
  |  |  ------------------
  ------------------
 1661|    586|                            while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9'))  // Consume the rest of exponent
  ------------------
  |  |  505|    906|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 306, False: 280]
  |  |  |  Branch (505:51): [True: 320, False: 266]
  |  |  |  Branch (505:51): [True: 306, False: 14]
  |  |  ------------------
  ------------------
 1662|    306|                                s.Take();
 1663|    280|                        }
 1664|  17.9k|                    }
 1665|  58.7k|                }
 1666|  2.82k|                else {  // positive exp
 1667|  2.82k|                    int maxExp = 308 - expFrac;
 1668|  3.14k|                    while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|  3.51k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 326, False: 2.82k]
  |  |  |  Branch (492:49): [True: 363, False: 2.78k]
  |  |  |  Branch (492:49): [True: 326, False: 37]
  |  |  ------------------
  ------------------
 1669|    326|                        exp = exp * 10 + static_cast<int>(s.Take() - '0');
 1670|    326|                        if (RAPIDJSON_UNLIKELY(exp > maxExp))
  ------------------
  |  |  505|    326|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 2, False: 324]
  |  |  ------------------
  ------------------
 1671|    326|                            RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);
  ------------------
  |  |  120|      4|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      2|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      4|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      2|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      2|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      2|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      2|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      2|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      2|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      2|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      2|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 2]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      4|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      2|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      4|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      2|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      4|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      2|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 2, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      4|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      2|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      2|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      2|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      2|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      2|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1671:29): [True: 2, False: 0]
  ------------------
 1672|    326|                    }
 1673|  2.82k|                }
 1674|  61.6k|            }
 1675|     30|            else
 1676|  61.6k|                RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell());
  ------------------
  |  |  120|     60|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     30|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|     60|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|     30|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|     30|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|     30|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|     30|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|     30|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|     30|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|     30|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|     30|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 30]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|     60|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|     30|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|     60|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|     30|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|     60|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|     30|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 30, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|     60|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|     30|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|     30|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|     30|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     30|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     30|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1676:17): [True: 30, False: 0]
  ------------------
 1677|       |
 1678|  61.6k|            if (expMinus)
  ------------------
  |  Branch (1678:17): [True: 58.7k, False: 2.82k]
  ------------------
 1679|  58.7k|                exp = -exp;
 1680|  61.6k|        }
 1681|       |
 1682|       |        // Finish parsing, call event according to the type of number.
 1683|  26.4M|        bool cont = true;
 1684|       |
 1685|  26.4M|        if (parseFlags & kParseNumbersAsStringsFlag) {
  ------------------
  |  Branch (1685:13): [Folded, False: 26.4M]
  ------------------
 1686|      0|            if (parseFlags & kParseInsituFlag) {
  ------------------
  |  Branch (1686:17): [True: 0, Folded]
  ------------------
 1687|      0|                s.Pop();  // Pop stack no matter if it will be used or not.
 1688|      0|                typename InputStream::Ch* head = is.PutBegin();
 1689|      0|                const size_t length = s.Tell() - startOffset;
 1690|      0|                RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
  ------------------
  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1690:17): [True: 0, False: 0]
  ------------------
 1691|       |                // unable to insert the \0 character here, it will erase the comma after this number
 1692|      0|                const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
 1693|      0|                cont = handler.RawNumber(str, SizeType(length), false);
 1694|      0|            }
 1695|      0|            else {
 1696|      0|                SizeType numCharsToCopy = static_cast<SizeType>(s.Length());
 1697|      0|                GenericStringStream<UTF8<NumberCharacter> > srcStream(s.Pop());
 1698|      0|                StackStream<typename TargetEncoding::Ch> dstStream(stack_);
 1699|      0|                while (numCharsToCopy--) {
  ------------------
  |  Branch (1699:24): [True: 0, False: 0]
  ------------------
 1700|      0|                    Transcoder<UTF8<typename TargetEncoding::Ch>, TargetEncoding>::Transcode(srcStream, dstStream);
 1701|      0|                }
 1702|      0|                dstStream.Put('\0');
 1703|      0|                const typename TargetEncoding::Ch* str = dstStream.Pop();
 1704|      0|                const SizeType length = static_cast<SizeType>(dstStream.Length()) - 1;
 1705|      0|                cont = handler.RawNumber(str, SizeType(length), true);
 1706|      0|            }
 1707|      0|        }
 1708|  26.4M|        else {
 1709|  26.4M|           size_t length = s.Length();
 1710|  26.4M|           const NumberCharacter* decimal = s.Pop();  // Pop stack no matter if it will be used or not.
 1711|       |
 1712|  26.4M|           if (useDouble) {
  ------------------
  |  Branch (1712:16): [True: 468k, False: 25.9M]
  ------------------
 1713|   468k|               int p = exp + expFrac;
 1714|   468k|               if (parseFlags & kParseFullPrecisionFlag)
  ------------------
  |  Branch (1714:20): [Folded, False: 468k]
  ------------------
 1715|      0|                   d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp);
 1716|   468k|               else
 1717|   468k|                   d = internal::StrtodNormalPrecision(d, p);
 1718|       |
 1719|       |               // Use > max, instead of == inf, to fix bogus warning -Wfloat-equal
 1720|   468k|               if (d > (std::numeric_limits<double>::max)()) {
  ------------------
  |  Branch (1720:20): [True: 2, False: 468k]
  ------------------
 1721|       |                   // Overflow
 1722|       |                   // TODO: internal::StrtodX should report overflow (or underflow)
 1723|      2|                   RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);
  ------------------
  |  |  120|      2|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      2|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      2|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      2|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      2|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      2|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      2|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      2|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      2|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      2|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      2|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 2]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      2|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      2|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      4|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      2|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      4|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      2|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 2, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      4|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      2|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      2|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      2|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      2|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      2|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1723:20): [True: 2, False: 0]
  ------------------
 1724|      2|               }
 1725|       |
 1726|   468k|               cont = handler.Double(minus ? -d : d);
  ------------------
  |  Branch (1726:38): [True: 88.3k, False: 380k]
  ------------------
 1727|   468k|           }
 1728|  25.9M|           else if (useNanOrInf) {
  ------------------
  |  Branch (1728:21): [True: 0, False: 25.9M]
  ------------------
 1729|      0|               cont = handler.Double(d);
 1730|      0|           }
 1731|  25.9M|           else {
 1732|  25.9M|               if (use64bit) {
  ------------------
  |  Branch (1732:20): [True: 74.8k, False: 25.9M]
  ------------------
 1733|  74.8k|                   if (minus)
  ------------------
  |  Branch (1733:24): [True: 59.8k, False: 15.0k]
  ------------------
 1734|  59.8k|                       cont = handler.Int64(static_cast<int64_t>(~i64 + 1));
 1735|  15.0k|                   else
 1736|  15.0k|                       cont = handler.Uint64(i64);
 1737|  74.8k|               }
 1738|  25.9M|               else {
 1739|  25.9M|                   if (minus)
  ------------------
  |  Branch (1739:24): [True: 139k, False: 25.7M]
  ------------------
 1740|   139k|                       cont = handler.Int(static_cast<int32_t>(~i + 1));
 1741|  25.7M|                   else
 1742|  25.7M|                       cont = handler.Uint(i);
 1743|  25.9M|               }
 1744|  25.9M|           }
 1745|  26.4M|        }
 1746|  26.4M|        if (RAPIDJSON_UNLIKELY(!cont))
  ------------------
  |  |  505|  26.4M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 26.4M]
  |  |  ------------------
  ------------------
 1747|       |            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, startOffset);
  ------------------
  |  |  120|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|      0|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      0|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      0|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      0|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      0|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|      0|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      0|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|      0|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      0|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      0|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      0|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      0|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1747:13): [True: 0, False: 0]
  ------------------
 1748|  26.4M|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE12NumberStreamINS_25GenericInsituStringStreamIS2_EEcLb0ELb0EE4TellEv:
 1422|  26.4M|        size_t Tell() { return is.Tell(); }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE7ConsumeINS4_12NumberStreamINS_25GenericInsituStringStreamIS2_EEcLb0ELb0EEEEEbRT_NSA_2ChE:
  895|   105M|    RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) {
  896|   105M|        if (RAPIDJSON_LIKELY(is.Peek() == expect)) {
  ------------------
  |  |  492|   105M|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 868k, False: 105M]
  |  |  ------------------
  ------------------
  897|   868k|            is.Take();
  898|   868k|            return true;
  899|   868k|        }
  900|   105M|        else
  901|   105M|            return false;
  902|   105M|    }
_ZNK9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE12NumberStreamINS_25GenericInsituStringStreamIS2_EEcLb0ELb0EE4PeekEv:
 1417|   215M|        RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE12NumberStreamINS_25GenericInsituStringStreamIS2_EEcLb0ELb0EE8TakePushEv:
 1418|  30.7M|        RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE12NumberStreamINS_25GenericInsituStringStreamIS2_EEcLb0ELb0EE6LengthEv:
 1423|  52.9M|        size_t Length() { return 0; }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE12NumberStreamINS_25GenericInsituStringStreamIS2_EEcLb0ELb0EE4TakeEv:
 1419|   948k|        RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE12NumberStreamINS_25GenericInsituStringStreamIS2_EEcLb0ELb0EE3PopEv:
 1424|  26.4M|        const StackCharacter* Pop() { return 0; }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEEC2EPS3_m:
  548|  8.71k|        stack_(stackAllocator, stackCapacity), parseResult_(), state_(IterativeParsingStartState) {}
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE16ClearStackOnExitC2ERS4_:
  702|  8.71k|        explicit ClearStackOnExit(GenericReader& r) : r_(r) {}
_ZN9rapidjson8internal15StreamLocalCopyINS_25GenericInsituStringStreamINS_4UTF8IcEEEELi1EEC2ERS5_:
  233|   113M|    StreamLocalCopy(Stream& original) : s(original), original_(original) {}
_ZN9rapidjson8internal15StreamLocalCopyINS_25GenericInsituStringStreamINS_4UTF8IcEEEELi1EED2Ev:
  234|   113M|    ~StreamLocalCopy() { original_ = s; }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE12NumberStreamINS_25GenericInsituStringStreamIS2_EEcLb0ELb0EEC2ERS4_RS7_:
 1415|  26.4M|        NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader;  }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE16ClearStackOnExitD2Ev:
  703|  8.71k|        ~ClearStackOnExit() { r_.ClearStack(); }

_ZN9rapidjson25GenericInsituStringStreamINS_4UTF8IcEEE4TakeEv:
  195|   132M|    Ch Take() { return *src_++; }
_ZN9rapidjson25GenericInsituStringStreamINS_4UTF8IcEEE8PutBeginEv:
  201|  5.80M|    Ch* PutBegin() { return dst_ = src_; }
_ZN9rapidjson25GenericInsituStringStreamINS_4UTF8IcEEE3PutEc:
  199|  45.8M|    void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }
  ------------------
  |  |  437|  45.8M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (199:22): [True: 45.8M, False: 0]
  ------------------
_ZN9rapidjson25GenericInsituStringStreamINS_4UTF8IcEEE6PutEndEPc:
  202|  5.80M|    size_t PutEnd(Ch* begin) { return static_cast<size_t>(dst_ - begin); }
_ZN9rapidjson25GenericInsituStringStreamINS_4UTF8IcEEE4PeekEv:
  194|   447M|    Ch Peek() { return *src_; }
_ZN9rapidjson25GenericInsituStringStreamINS_4UTF8IcEEE4TellEv:
  196|  66.4M|    size_t Tell() { return static_cast<size_t>(src_ - head_); }
_ZN9rapidjson25GenericInsituStringStreamINS_4UTF8IcEEEC2EPc:
  191|  8.71k|    GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {}

LLVMFuzzerTestOneInput:
   48|  3.48k|extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataSize) {
   49|  3.48k|    if (dataSize > 1024 * 1024) {
  ------------------
  |  Branch (49:9): [True: 0, False: 3.48k]
  ------------------
   50|      0|        return 0;
   51|      0|    }
   52|       |
   53|  3.48k|    Importer importer;
   54|       |    // Force GLB binary format only (see assimp_fuzzer_gltf.cc for text glTF)
   55|  3.48k|    if (!AssimpFuzz::ForceFormat(importer, "glb")) {
  ------------------
  |  Branch (55:9): [True: 0, False: 3.48k]
  ------------------
   56|      0|        return 0;
   57|      0|    }
   58|       |
   59|  3.48k|    unsigned int flags = aiProcessPreset_TargetRealtime_Quality | aiProcess_ValidateDataStructure;
   60|  3.48k|    const aiScene *sc = importer.ReadFileFromMemory(data, dataSize, flags, "glb");
   61|       |
   62|  3.48k|    return 0;
   63|  3.48k|}

_ZN10AssimpFuzz11ForceFormatERN6Assimp8ImporterEPKc:
   53|  3.48k|inline bool ForceFormat(Assimp::Importer& importer, const char* targetExtension) {
   54|  3.48k|    size_t count = importer.GetImporterCount();
   55|  3.48k|    std::vector<Assimp::BaseImporter*> toRemove;
   56|  3.48k|    bool found = false;
   57|       |
   58|   170k|    for (size_t i = 0; i < count; ++i) {
  ------------------
  |  Branch (58:24): [True: 167k, False: 3.48k]
  ------------------
   59|   167k|        const aiImporterDesc* desc = importer.GetImporterInfo(i);
   60|   167k|        Assimp::BaseImporter* imp = importer.GetImporter(i);
   61|       |        
   62|   167k|        if (!desc || !imp) continue;
  ------------------
  |  Branch (62:13): [True: 0, False: 167k]
  |  Branch (62:22): [True: 0, False: 167k]
  ------------------
   63|       |
   64|       |        // Check if the importer supports the target extension
   65|       |        // mFileExtensions is a space-separated list (e.g., "obj mod")
   66|       |        // We wrap target in spaces or check bounds to be precise, 
   67|       |        // but for fuzzing, a simple strstr is usually sufficient 
   68|       |        // if the target string is unique enough (e.g. "gltf", "obj").
   69|       |        // A more robust check:
   70|       |        
   71|   167k|        bool isTarget = false;
   72|   167k|        const char* extList = desc->mFileExtensions;
   73|   167k|        if (!extList) {
  ------------------
  |  Branch (73:13): [True: 0, False: 167k]
  ------------------
   74|      0|            toRemove.push_back(imp);
   75|      0|            continue;
   76|      0|        }
   77|   167k|        const size_t targetLen = strlen(targetExtension);
   78|       |
   79|   167k|        const char* p = extList;
   80|   167k|        while ((p = strstr(p, targetExtension)) != nullptr) {
  ------------------
  |  Branch (80:16): [True: 6.97k, False: 160k]
  ------------------
   81|       |            // Check boundaries
   82|  6.97k|            const char prev = (p == extList) ? ' ' : *(p - 1);
  ------------------
  |  Branch (82:31): [True: 0, False: 6.97k]
  ------------------
   83|  6.97k|            const char next = *(p + targetLen);
   84|       |            
   85|  6.97k|            if (prev == ' ' && (next == ' ' || next == '\0')) {
  ------------------
  |  Branch (85:17): [True: 6.97k, False: 0]
  |  Branch (85:33): [True: 3.48k, False: 3.48k]
  |  Branch (85:48): [True: 3.48k, False: 0]
  ------------------
   86|  6.97k|                isTarget = true;
   87|  6.97k|                break;
   88|  6.97k|            }
   89|      0|            p++;
   90|      0|        }
   91|       |
   92|   167k|        if (isTarget) {
  ------------------
  |  Branch (92:13): [True: 6.97k, False: 160k]
  ------------------
   93|  6.97k|            found = true;
   94|   160k|        } else {
   95|   160k|            toRemove.push_back(imp);
   96|   160k|        }
   97|   167k|    }
   98|       |
   99|   160k|    for (auto* imp : toRemove) {
  ------------------
  |  Branch (99:20): [True: 160k, False: 3.48k]
  ------------------
  100|   160k|        importer.UnregisterLoader(imp);
  101|   160k|        delete imp;  // Free the unregistered importer to prevent memory leaks
  102|   160k|    }
  103|       |
  104|  3.48k|    return found;
  105|  3.48k|}

_ZN6Assimp10TXmlParserIN4pugi8xml_nodeEEC2Ev:
  256|  6.97k|        mDoc(nullptr),
  257|  6.97k|        mData() {
  258|       |    // empty
  259|  6.97k|}
_ZN6Assimp10TXmlParserIN4pugi8xml_nodeEE5clearEv:
  267|  6.97k|inline void TXmlParser<TNodeType>::clear() {
  268|  6.97k|    if (mData.empty()) {
  ------------------
  |  Branch (268:9): [True: 6.97k, False: 0]
  ------------------
  269|  6.97k|        if (mDoc) {
  ------------------
  |  Branch (269:13): [True: 0, False: 6.97k]
  ------------------
  270|      0|            delete mDoc;
  271|      0|        }
  272|  6.97k|        mDoc = nullptr;
  273|  6.97k|        return;
  274|  6.97k|    }
  275|       |
  276|      0|    mData.clear();
  277|      0|    delete mDoc;
  278|      0|    mDoc = nullptr;
  279|      0|}
_ZN6Assimp10TXmlParserIN4pugi8xml_nodeEED2Ev:
  262|  6.97k|inline TXmlParser<TNodeType>::~TXmlParser() {
  263|  6.97k|    clear();
  264|  6.97k|}

