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

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

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

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

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

_ZN6Assimp11AMFImporter5ClearEv:
   69|  3.24k|void AMFImporter::Clear() {
   70|  3.24k|    mNodeElement_Cur = nullptr;
   71|  3.24k|    mUnit.clear();
   72|  3.24k|    mMaterial_Converted.clear();
   73|  3.24k|    mTexture_Converted.clear();
   74|       |    // Delete all elements
   75|  3.24k|    if (!mNodeElement_List.empty()) {
  ------------------
  |  Branch (75:9): [True: 0, False: 3.24k]
  ------------------
   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.24k|}
_ZN6Assimp11AMFImporterC2Ev:
   85|  3.24k|        mNodeElement_Cur(nullptr),
   86|  3.24k|        mXmlParser(nullptr) {
   87|       |    // empty
   88|  3.24k|}
_ZN6Assimp11AMFImporterD2Ev:
   90|  3.24k|AMFImporter::~AMFImporter() {
   91|  3.24k|    delete mXmlParser;
   92|       |    // Clear() is accounting if data already is deleted. So, just check again if all data is deleted.
   93|  3.24k|    Clear();
   94|  3.24k|}
_ZNK6Assimp11AMFImporter7GetInfoEv:
  487|  3.24k|const aiImporterDesc *AMFImporter::GetInfo() const {
  488|  3.24k|    return &Description;
  489|  3.24k|}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

_ZN6Assimp17Q3BSPFileImporterC2Ev:
  137|  3.24k|        m_pCurrentMesh(nullptr), m_pCurrentFace(nullptr) {
  138|       |    // empty
  139|  3.24k|}
_ZN6Assimp17Q3BSPFileImporterD2Ev:
  143|  3.24k|Q3BSPFileImporter::~Q3BSPFileImporter() {
  144|  3.24k|    clear();
  145|  3.24k|}
_ZN6Assimp17Q3BSPFileImporter5clearEv:
  148|  3.24k|void Q3BSPFileImporter::clear() {
  149|  3.24k|    for (FaceMap::iterator it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); ++it) {
  ------------------
  |  Branch (149:62): [True: 0, False: 3.24k]
  ------------------
  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.24k|}
_ZNK6Assimp17Q3BSPFileImporter7GetInfoEv:
  168|  3.24k|const aiImporterDesc *Q3BSPFileImporter::GetInfo() const {
  169|  3.24k|    return &desc;
  170|  3.24k|}

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

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

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

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

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

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

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

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

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

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

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

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

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

_ZN6Assimp11X3DImporterC2Ev:
  192|  3.24k|        mNodeElementCur(nullptr),
  193|  3.24k|        mScene(nullptr),
  194|  3.24k|        mpIOHandler(nullptr) {
  195|       |    // empty
  196|  3.24k|}
_ZN6Assimp11X3DImporterD2Ev:
  198|  3.24k|X3DImporter::~X3DImporter() {
  199|       |    // Clear() is accounting if data already is deleted. So, just check again if all data is deleted.
  200|  3.24k|    Clear();
  201|  3.24k|}
_ZN6Assimp11X3DImporter5ClearEv:
  203|  3.24k|void X3DImporter::Clear() {
  204|  3.24k|    mNodeElementCur = nullptr;
  205|       |    // Delete all elements
  206|  3.24k|    if (!NodeElement_List.empty()) {
  ------------------
  |  Branch (206:9): [True: 0, False: 3.24k]
  ------------------
  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.24k|}
_ZNK6Assimp11X3DImporter7GetInfoEv:
  340|  3.24k|const aiImporterDesc *X3DImporter::GetInfo() const {
  341|  3.24k|    return &Description;
  342|  3.24k|}

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

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

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

_ZN6Assimp12glTFImporterC2Ev:
  148|  3.24k|        mScene(nullptr) {
  149|       |    // empty
  150|  3.24k|}
_ZNK6Assimp12glTFImporter7GetInfoEv:
  152|  9.80k|const aiImporterDesc *glTFImporter::GetInfo() const {
  153|  9.80k|    return &desc;
  154|  9.80k|}
_ZNK6Assimp12glTFImporter7CanReadERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEPNS_8IOSystemEb:
  156|  4.23k|bool glTFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /* checkSig */) const {
  157|  4.23k|    Asset asset(pIOHandler);
  158|  4.23k|    try {
  159|  4.23k|        asset.Load(pFile,
  160|  4.23k|                   CheckMagicToken(
  161|  4.23k|                       pIOHandler, pFile, AI_GLB_MAGIC_NUMBER, 1, 0,
  ------------------
  |  |  127|  4.23k|#define AI_GLB_MAGIC_NUMBER "glTF"
  ------------------
  162|  4.23k|                       static_cast<unsigned int>(strlen(AI_GLB_MAGIC_NUMBER))));
  ------------------
  |  |  127|  4.23k|#define AI_GLB_MAGIC_NUMBER "glTF"
  ------------------
  163|  4.23k|        return asset.asset;
  164|  4.23k|    } catch (...) {
  165|  3.67k|        return false;
  166|  3.67k|    }
  167|  4.23k|}
_ZNK6Assimp12glTFImporter15ImportMaterialsERN4glTF5AssetE:
  169|     80|void glTFImporter::ImportMaterials(Asset &r) const {
  170|     80|    mScene->mNumMaterials = r.materials.Size();
  171|     80|    if (mScene->mNumMaterials == 0) {
  ------------------
  |  Branch (171:9): [True: 80, False: 0]
  ------------------
  172|     80|        createDefaultMaterial(mScene);
  173|     80|        return;
  174|     80|    }
  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|     80|void glTFImporter::ImportMeshes(Asset &r) {
  202|     80|    std::vector<aiMesh *> meshes;
  203|       |
  204|     80|    unsigned int k = 0;
  205|     80|    meshOffsets.clear();
  206|       |
  207|     80|    for (unsigned int m = 0; m < r.meshes.Size(); ++m) {
  ------------------
  |  Branch (207:30): [True: 0, False: 80]
  ------------------
  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|     80|    meshOffsets.push_back(k);
  458|       |
  459|     80|    CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes);
  460|     80|}
_ZNK6Assimp12glTFImporter13ImportCamerasERN4glTF5AssetE:
  462|     80|void glTFImporter::ImportCameras(Asset &r) const {
  463|     80|    if (!r.cameras.Size()) {
  ------------------
  |  Branch (463:9): [True: 80, False: 0]
  ------------------
  464|     80|        return;
  465|     80|    }
  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|     80|void glTFImporter::ImportLights(Asset &r) const {
  491|     80|    if (!r.lights.Size()) {
  ------------------
  |  Branch (491:9): [True: 80, False: 0]
  ------------------
  492|     80|        return;
  493|     80|    }
  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|     80|void glTFImporter::ImportNodes(Asset &r) {
  608|     80|    if (!r.scene) {
  ------------------
  |  Branch (608:9): [True: 80, False: 0]
  ------------------
  609|     80|        return;
  610|     80|    }
  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|     80|void glTFImporter::ImportEmbeddedTextures(Asset &r) {
  630|     80|    embeddedTexIdxs.resize(r.images.Size(), -1);
  631|       |
  632|     80|    int numEmbeddedTexs = 0;
  633|     80|    for (size_t i = 0; i < r.images.Size(); ++i) {
  ------------------
  |  Branch (633:24): [True: 0, False: 80]
  ------------------
  634|      0|        if (r.images[i].HasData())
  ------------------
  |  Branch (634:13): [True: 0, False: 0]
  ------------------
  635|      0|            numEmbeddedTexs += 1;
  636|      0|    }
  637|       |
  638|     80|    if (numEmbeddedTexs == 0) {
  ------------------
  |  Branch (638:9): [True: 80, False: 0]
  ------------------
  639|     80|        return;
  640|     80|    }
  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|     80|void glTFImporter::ImportCommonMetadata(const Asset &a) const {
  678|     80|    ai_assert(mScene->mMetaData == nullptr);
  679|       |
  680|     80|    const bool hasVersion = !a.asset.version.empty();
  681|     80|    const bool hasGenerator = !a.asset.generator.empty();
  682|     80|    const bool hasCopyright = !a.asset.copyright.empty();
  683|     80|    if (hasVersion || hasGenerator || hasCopyright) {
  ------------------
  |  Branch (683:9): [True: 80, False: 0]
  |  Branch (683:23): [True: 0, False: 0]
  |  Branch (683:39): [True: 0, False: 0]
  ------------------
  684|     80|        mScene->mMetaData = new aiMetadata;
  685|     80|        if (hasVersion) {
  ------------------
  |  Branch (685:13): [True: 80, False: 0]
  ------------------
  686|     80|            mScene->mMetaData->Add(AI_METADATA_SOURCE_FORMAT_VERSION, aiString(a.asset.version));
  687|     80|        }
  688|     80|        if (hasGenerator) {
  ------------------
  |  Branch (688:13): [True: 22, False: 58]
  ------------------
  689|     22|            mScene->mMetaData->Add(AI_METADATA_SOURCE_GENERATOR, aiString(a.asset.generator));
  690|     22|        }
  691|     80|        if (hasCopyright) {
  ------------------
  |  Branch (691:13): [True: 13, False: 67]
  ------------------
  692|       |            mScene->mMetaData->Add(AI_METADATA_SOURCE_COPYRIGHT, aiString(a.asset.copyright));
  693|     13|        }
  694|     80|    }
  695|     80|}
_ZN6Assimp12glTFImporter14InternReadFileERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEP7aiScenePNS_8IOSystemE:
  697|     80|void glTFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
  698|       |    // clean all member arrays
  699|     80|    meshOffsets.clear();
  700|     80|    embeddedTexIdxs.clear();
  701|       |
  702|     80|    this->mScene = pScene;
  703|       |
  704|       |    // read the asset file
  705|     80|    Asset asset(pIOHandler);
  706|     80|    asset.Load(pFile,
  707|     80|               CheckMagicToken(
  708|     80|                   pIOHandler, pFile, AI_GLB_MAGIC_NUMBER, 1, 0,
  ------------------
  |  |  127|     80|#define AI_GLB_MAGIC_NUMBER "glTF"
  ------------------
  709|     80|                   static_cast<unsigned int>(strlen(AI_GLB_MAGIC_NUMBER))));
  ------------------
  |  |  127|     80|#define AI_GLB_MAGIC_NUMBER "glTF"
  ------------------
  710|       |
  711|       |    //
  712|       |    // Copy the data out
  713|       |    //
  714|       |
  715|     80|    ImportEmbeddedTextures(asset);
  716|     80|    ImportMaterials(asset);
  717|       |
  718|     80|    ImportMeshes(asset);
  719|       |
  720|     80|    ImportCameras(asset);
  721|     80|    ImportLights(asset);
  722|       |
  723|     80|    ImportNodes(asset);
  724|     80|    ImportCommonMetadata(asset);
  725|       |
  726|     80|    if (pScene->mNumMeshes == 0) {
  ------------------
  |  Branch (726:9): [True: 80, False: 0]
  ------------------
  727|       |        pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
  728|     80|    }
  729|     80|}
glTFImporter.cpp:_ZN12_GLOBAL__N_121createDefaultMaterialEP7aiScene:
  135|     80|    void createDefaultMaterial(aiScene *scene) {
  136|     80|        if (scene == nullptr) {
  ------------------
  |  Branch (136:13): [True: 0, False: 80]
  ------------------
  137|      0|            return;
  138|      0|        }
  139|     80|        scene->mNumMaterials = 1;
  140|     80|        scene->mMaterials = nullptr;
  141|     80|        scene->mMaterials = new aiMaterial *[1];
  142|     80|        scene->mMaterials[0] = new aiMaterial();
  143|     80|    }

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

_ZN5glTF26ObjectD2Ev:
  394|  37.4k|    virtual ~Object() = default;
_ZN5glTF215CustomExtensionD2Ev:
  367|   106k|    ~CustomExtension() = default;
_ZN5glTF210AttribType10FromStringEPKc:
  308|  6.79k|    inline static Value FromString(const char *str) {
  309|  22.9k|        for (size_t i = 0; i < NUM_VALUES; ++i) {
  ------------------
  |  Branch (309:28): [True: 22.5k, False: 347]
  ------------------
  310|  22.5k|            if (strcmp(data<0>::infos[i].name, str) == 0) {
  ------------------
  |  Branch (310:17): [True: 6.44k, False: 16.1k]
  ------------------
  311|  6.44k|                return static_cast<Value>(i);
  312|  6.44k|            }
  313|  22.5k|        }
  314|    347|        return SCALAR;
  315|  6.79k|    }
_ZN5glTF210AttribType16GetNumComponentsENS0_5ValueE:
  321|  23.3k|    inline static unsigned int GetNumComponents(Value type) {
  322|  23.3k|        return data<0>::infos[static_cast<size_t>(type)].numComponents;
  323|  23.3k|    }
_ZNK5glTF215CustomExtensioncvbEv:
  353|  14.8k|    operator bool() const {
  354|  14.8k|        return Size() != 0;
  355|  14.8k|    }
_ZNK5glTF215CustomExtension4SizeEv:
  357|  14.8k|    size_t Size() const {
  358|  14.8k|        if (mValues.isPresent) {
  ------------------
  |  Branch (358:13): [True: 0, False: 14.8k]
  ------------------
  359|      0|            return mValues.value.size();
  360|  14.8k|        } else if (mStringValue.isPresent || mDoubleValue.isPresent || mUint64Value.isPresent || mInt64Value.isPresent || mBoolValue.isPresent) {
  ------------------
  |  Branch (360:20): [True: 0, False: 14.8k]
  |  Branch (360:46): [True: 0, False: 14.8k]
  |  Branch (360:72): [True: 0, False: 14.8k]
  |  Branch (360:98): [True: 0, False: 14.8k]
  |  Branch (360:123): [True: 0, False: 14.8k]
  ------------------
  361|      0|            return 1;
  362|      0|        }
  363|  14.8k|        return 0;
  364|  14.8k|    }
_ZNK5glTF26Extras9HasExtrasEv:
  376|  14.8k|    inline bool HasExtras() const {
  377|  14.8k|        return !mValues.empty();
  378|  14.8k|    }
_ZN5glTF26Buffer10GetPointerEv:
  520|  6.05k|    uint8_t *GetPointer() { return mData.get(); }
_ZN5glTF26Buffer13MarkAsSpecialEv:
  522|  4.22k|    void MarkAsSpecial() { mIsSpecial = true; }
_ZN5glTF28Accessor7Indexer7GetUIntEi:
  596|  25.0k|        inline unsigned int GetUInt(int i) {
  597|  25.0k|            return GetValue<unsigned int>(i);
  598|  25.0k|        }
_ZNK5glTF28Accessor7Indexer7IsValidEv:
  600|    947|        inline bool IsValid() const {
  601|    947|            return data != nullptr;
  602|    947|        }
_ZN5glTF28Accessor10GetIndexerEv:
  605|    956|    inline Indexer GetIndexer() {
  606|    956|        return Indexer(*this);
  607|    956|    }
_ZNK5glTF25Image7HasDataEv:
  699|     95|    inline bool HasData() const { return mDataLength > 0; }
_ZNK5glTF25Image13GetDataLengthEv:
  701|     47|    inline size_t GetDataLength() const { return mDataLength; }
_ZN5glTF221PbrSpecularGlossinessC2Ev:
  754|  3.23k|    PbrSpecularGlossiness() { SetDefaults(); }
_ZN5glTF216MaterialSpecularC2Ev:
  764|  3.23k|    MaterialSpecular() { SetDefaults(); }
_ZN5glTF213MaterialSheenC2Ev:
  774|  3.23k|    MaterialSheen() { SetDefaults(); }
_ZN5glTF214MaterialVolumeC2Ev:
  797|  3.23k|    MaterialVolume() { SetDefaults(); }
_ZN5glTF211MaterialIORC2Ev:
  804|  3.23k|    MaterialIOR() { SetDefaults(); }
_ZN5glTF224MaterialEmissiveStrengthC2Ev:
  811|  3.23k|    MaterialEmissiveStrength() { SetDefaults(); }
_ZN5glTF218MaterialAnisotropyC2Ev:
  820|  3.23k|    MaterialAnisotropy() { SetDefaults(); }
_ZN5glTF28MaterialC2Ev:
  868|  3.23k|    Material() { SetDefaults(); }
_ZN5glTF24Mesh9PrimitiveC2Ev:
  901|  1.77k|        Primitive(): ngonEncoded(false) {}
_ZN5glTF27SamplerC2Ev:
  950|     58|    Sampler() { SetDefaults(); }
_ZN5glTF25AssetC2EPN6Assimp8IOSystemEPN9rapidjson36IGenericRemoteSchemaDocumentProviderINS4_21GenericSchemaDocumentINS4_12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEESB_EEEE:
 1179|  6.32k|            mDicts(),
 1180|  6.32k|            extensionsUsed(),
 1181|  6.32k|            extensionsRequired(),
 1182|  6.32k|            asset(),
 1183|  6.32k|            extras(nullptr),
 1184|  6.32k|            accessors(*this, "accessors"),
 1185|  6.32k|            animations(*this, "animations"),
 1186|  6.32k|            buffers(*this, "buffers"),
 1187|  6.32k|            bufferViews(*this, "bufferViews"),
 1188|  6.32k|            cameras(*this, "cameras"),
 1189|  6.32k|            lights(*this, "lights", "KHR_lights_punctual"),
 1190|  6.32k|            images(*this, "images"),
 1191|  6.32k|            materials(*this, "materials"),
 1192|  6.32k|            meshes(*this, "meshes"),
 1193|  6.32k|            nodes(*this, "nodes"),
 1194|  6.32k|            samplers(*this, "samplers"),
 1195|  6.32k|            scenes(*this, "scenes"),
 1196|  6.32k|            skins(*this, "skins"),
 1197|  6.32k|            textures(*this, "textures") ,
 1198|  6.32k|            mIOSystem(io),
 1199|  6.32k|            mSchemaDocumentProvider(schemaDocumentProvider) {
 1200|       |        // empty
 1201|  6.32k|    }
_ZN5glTF217ComponentTypeSizeENS_13ComponentTypeE:
  197|  22.8k|inline unsigned int ComponentTypeSize(ComponentType t) {
  198|  22.8k|    switch (t) {
  199|     78|    case ComponentType_SHORT:
  ------------------
  |  Branch (199:5): [True: 78, False: 22.7k]
  ------------------
  200|  3.54k|    case ComponentType_UNSIGNED_SHORT:
  ------------------
  |  Branch (200:5): [True: 3.47k, False: 19.4k]
  ------------------
  201|  3.54k|        return 2;
  202|       |
  203|  3.15k|    case ComponentType_UNSIGNED_INT:
  ------------------
  |  Branch (203:5): [True: 3.15k, False: 19.7k]
  ------------------
  204|  14.6k|    case ComponentType_FLOAT:
  ------------------
  |  Branch (204:5): [True: 11.5k, False: 11.3k]
  ------------------
  205|  14.6k|        return 4;
  206|       |
  207|  4.51k|    case ComponentType_BYTE:
  ------------------
  |  Branch (207:5): [True: 4.51k, False: 18.3k]
  ------------------
  208|  4.63k|    case ComponentType_UNSIGNED_BYTE:
  ------------------
  |  Branch (208:5): [True: 121, False: 22.7k]
  ------------------
  209|  4.63k|        return 1;
  210|     36|    default:
  ------------------
  |  Branch (210:5): [True: 36, False: 22.8k]
  ------------------
  211|     36|        throw DeadlyImportError("GLTF: Unsupported Component Type ", ai_to_string(t));
  212|  22.8k|    }
  213|  22.8k|}
_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: 11, False: 69]
  ------------------
 1247|     11|        context += " (\"" + name + "\")";
 1248|     11|    }
 1249|     80|    return context;
 1250|     80|}
_ZN5glTF25Asset10ExtensionsC2Ev:
 1142|  6.32k|        Extensions() = default;
_ZN5glTF25Asset18RequiredExtensionsC2Ev:
 1152|  6.32k|        RequiredExtensions() = default;
_ZN5glTF213AssetMetadataC2Ev:
 1104|  6.32k|    AssetMetadata() = default;
_ZN5glTF212LazyDictBaseD2Ev:
 1026|  88.5k|    virtual ~LazyDictBase() = default;
_ZN5glTF215CustomExtensionC2Ev:
  366|  72.8k|    CustomExtension() = default;
_ZN5glTF215CustomExtensionC2ERKS0_:
  368|  33.4k|    CustomExtension(const CustomExtension &other) = default;
_ZN5glTF215CustomExtensionaSERKS0_:
  369|  1.72k|    CustomExtension& operator=(const CustomExtension&) = default;
_ZN5glTF25SceneC2Ev:
  959|  1.98k|    Scene() = default;
_ZN5glTF24NodeC2Ev:
  935|  11.8k|    Node() = default;
_ZN5glTF24MeshC2Ev:
  909|  1.79k|    Mesh() = default;
_ZN5glTF28AccessorC2Ev:
  609|  7.11k|    Accessor() = default;
_ZN5glTF27TextureC2Ev:
  989|     71|    Texture() = default;
_ZN5glTF24SkinC2Ev:
  974|    389|    Skin() = default;
_ZNK5glTF28LazyDictINS_8MaterialEE4SizeEv:
 1086|  1.80k|    inline unsigned int Size() const { return unsigned(mObjs.size()); }
_ZN5glTF28LazyDictINS_8MaterialEEixEm:
 1088|  1.28k|    inline T &operator[](size_t i) { return *mObjs[i]; }
_ZNK5glTF28LazyDictINS_4MeshEE4SizeEv:
 1086|  10.1k|    inline unsigned int Size() const { return unsigned(mObjs.size()); }
_ZN5glTF28LazyDictINS_4MeshEEixEm:
 1088|  3.17k|    inline T &operator[](size_t i) { return *mObjs[i]; }
_ZNK5glTF28LazyDictINS_6CameraEE4SizeEv:
 1086|  1.52k|    inline unsigned int Size() const { return unsigned(mObjs.size()); }
_ZNK5glTF28LazyDictINS_5LightEE4SizeEv:
 1086|  1.52k|    inline unsigned int Size() const { return unsigned(mObjs.size()); }
_ZNK5glTF28LazyDictINS_9AnimationEE4SizeEv:
 1086|  1.38k|    inline unsigned int Size() const { return unsigned(mObjs.size()); }
_ZNK5glTF28LazyDictINS_5ImageEE4SizeEv:
 1086|  3.75k|    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.22k|inline Buffer::~Buffer() {
  566|  4.22k|    for (SEncodedRegion *reg : EncodedRegion_List) delete reg;
  ------------------
  |  Branch (566:30): [True: 0, False: 4.22k]
  ------------------
  567|  4.22k|}
_ZN5glTF26Object10FindStringERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEEPKc:
  235|  2.10k|inline Value *Object::FindString(Value &val, const char *memberId) {
  236|  2.10k|    return FindStringInContext(val, memberId, id.c_str(), name.c_str());
  237|  2.10k|}
_ZN5glTF26Object8FindUIntERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEEPKc:
  243|  59.4k|inline Value *Object::FindUInt(Value &val, const char *memberId) {
  244|  59.4k|    return FindUIntInContext(val, memberId, id.c_str(), name.c_str());
  245|  59.4k|}
_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|  86.8k|inline Value *Object::FindObject(Value &val, const char *memberId) {
  252|  86.8k|    return FindObjectInContext(val, memberId, id.c_str(), name.c_str());
  253|  86.8k|}
_ZN5glTF26Object14ReadExtensionsERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEE:
  259|  30.3k|inline void Object::ReadExtensions(Value &val) {
  260|  30.3k|    if (Value *curExtensions = FindObject(val, "extensions")) {
  ------------------
  |  Branch (260:16): [True: 0, False: 30.3k]
  ------------------
  261|      0|        this->customExtensions = glTF2::ReadExtensions("extensions", *curExtensions);
  262|      0|    }
  263|  30.3k|}
_ZN5glTF26Object10ReadExtrasERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEE:
  265|  30.3k|inline void Object::ReadExtras(Value &val) {
  266|  30.3k|    if (Value *curExtras = FindObject(val, "extras")) {
  ------------------
  |  Branch (266:16): [True: 8.23k, False: 22.0k]
  ------------------
  267|  8.23k|        this->extras = glTF2::ReadExtras(*curExtras);
  268|  8.23k|    }
  269|  30.3k|}
_ZN5glTF26Buffer14LoadFromStreamERN6Assimp8IOStreamEmm:
  625|  1.87k|inline bool Buffer::LoadFromStream(IOStream &stream, size_t length, size_t baseOffset) {
  626|  1.87k|    byteLength = length ? length : stream.FileSize();
  ------------------
  |  Branch (626:18): [True: 1.87k, False: 0]
  ------------------
  627|       |
  628|  1.87k|    if (byteLength > stream.FileSize()) {
  ------------------
  |  Branch (628:9): [True: 47, False: 1.82k]
  ------------------
  629|     47|        throw DeadlyImportError("GLTF: Invalid byteLength exceeds size of actual data.");
  630|     47|    }
  631|       |
  632|  1.82k|    if (baseOffset) {
  ------------------
  |  Branch (632:9): [True: 1.82k, False: 0]
  ------------------
  633|  1.82k|        stream.Seek(baseOffset, aiOrigin_SET);
  634|  1.82k|    }
  635|       |
  636|  1.82k|    mData.reset(new uint8_t[byteLength], std::default_delete<uint8_t[]>());
  637|       |
  638|  1.82k|    if (stream.Read(mData.get(), byteLength, 1) != 1) {
  ------------------
  |  Branch (638:9): [True: 15, False: 1.81k]
  ------------------
  639|     15|        return false;
  640|     15|    }
  641|  1.81k|    return true;
  642|  1.82k|}
_ZN5glTF210BufferView4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
  765|  6.69k|inline void BufferView::Read(Value &obj, Asset &r) {
  766|  6.69k|    if (Value *bufferVal = FindUInt(obj, "buffer")) {
  ------------------
  |  Branch (766:16): [True: 6.68k, False: 14]
  ------------------
  767|  6.68k|        buffer = r.buffers.Retrieve(bufferVal->GetUint());
  768|  6.68k|    }
  769|       |
  770|  6.69k|    if (!buffer) {
  ------------------
  |  Branch (770:9): [True: 11, False: 6.68k]
  ------------------
  771|     11|        throw DeadlyImportError("GLTF: Buffer view without valid buffer.");
  772|     11|    }
  773|       |
  774|  6.68k|    byteOffset = MemberOrDefault(obj, "byteOffset", size_t(0));
  775|  6.68k|    byteLength = MemberOrDefault(obj, "byteLength", size_t(0));
  776|  6.68k|    byteStride = MemberOrDefault(obj, "byteStride", 0u);
  777|       |
  778|       |    // Check length
  779|  6.68k|    if ((byteOffset + byteLength) > buffer->byteLength) {
  ------------------
  |  Branch (779:9): [True: 14, False: 6.67k]
  ------------------
  780|     14|        throw DeadlyImportError("GLTF: Buffer view with offset/length (", byteOffset, "/", byteLength, ") is out of range.");
  781|     14|    }
  782|  6.68k|}
_ZN5glTF28Accessor4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
  871|  7.11k|inline void Accessor::Read(Value &obj, Asset &r) {
  872|  7.11k|    if (Value *bufferViewVal = FindUInt(obj, "bufferView")) {
  ------------------
  |  Branch (872:16): [True: 6.97k, False: 136]
  ------------------
  873|  6.97k|        bufferView = r.bufferViews.Retrieve(bufferViewVal->GetUint());
  874|  6.97k|    }
  875|       |
  876|  7.11k|    byteOffset = MemberOrDefault(obj, "byteOffset", size_t(0));
  877|  7.11k|    componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE);
  878|  7.11k|    {
  879|  7.11k|        const Value *countValue = FindUInt(obj, "count");
  880|  7.11k|        if (!countValue) {
  ------------------
  |  Branch (880:13): [True: 10, False: 7.10k]
  ------------------
  881|     10|            throw DeadlyImportError("A count value is required, when reading ", id.c_str(), name.empty() ? "" : " (" + name + ")");
  ------------------
  |  Branch (881:93): [True: 8, False: 2]
  ------------------
  882|     10|        }
  883|  7.10k|        count = countValue->GetUint();
  884|  7.10k|    }
  885|       |
  886|      0|    const char *typestr;
  887|  7.10k|    type = ReadMember(obj, "type", typestr) ? AttribType::FromString(typestr) : AttribType::SCALAR;
  ------------------
  |  Branch (887:12): [True: 6.79k, False: 310]
  ------------------
  888|       |
  889|  7.10k|    if (bufferView) {
  ------------------
  |  Branch (889:9): [True: 6.91k, False: 184]
  ------------------
  890|       |        // Check length
  891|  6.91k|        unsigned long long byteLength = count > 0
  ------------------
  |  Branch (891:41): [True: 6.90k, False: 11]
  ------------------
  892|  6.91k|            ? (unsigned long long)GetStride() * (unsigned long long)(count - 1) + (unsigned long long)GetElementSize()
  893|  6.91k|            : 0;
  894|       |
  895|       |        // handle integer overflow
  896|  6.91k|        if (byteLength < count) {
  ------------------
  |  Branch (896:13): [True: 0, False: 6.91k]
  ------------------
  897|      0|            throw DeadlyImportError("GLTF: Accessor with offset/count (", byteOffset, "/", count, ") is out of range.");
  898|      0|        }
  899|       |
  900|  6.91k|        if ((byteOffset + byteLength) > bufferView->byteLength || (bufferView->byteOffset + byteOffset + byteLength) > bufferView->buffer->byteLength) {
  ------------------
  |  Branch (900:13): [True: 70, False: 6.84k]
  |  Branch (900:67): [True: 0, False: 6.84k]
  ------------------
  901|     44|            throw DeadlyImportError("GLTF: Accessor with offset/length (", byteOffset, "/", byteLength, ") is out of range.");
  902|     44|        }
  903|  6.91k|    }
  904|       |
  905|  7.05k|    if (Value *sparseValue = FindObject(obj, "sparse")) {
  ------------------
  |  Branch (905:16): [True: 0, False: 7.05k]
  ------------------
  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.05k|}
_ZN5glTF28Accessor16GetNumComponentsEv:
  959|  23.3k|inline unsigned int Accessor::GetNumComponents() {
  960|  23.3k|    return AttribType::GetNumComponents(type);
  961|  23.3k|}
_ZN5glTF28Accessor20GetBytesPerComponentEv:
  963|  22.8k|inline unsigned int Accessor::GetBytesPerComponent() {
  964|  22.8k|    return int(ComponentTypeSize(componentType));
  965|  22.8k|}
_ZN5glTF28Accessor14GetElementSizeEv:
  967|  22.8k|inline unsigned int Accessor::GetElementSize() {
  968|  22.8k|    return GetNumComponents() * GetBytesPerComponent();
  969|  22.8k|}
_ZN5glTF28Accessor10GetPointerEv:
  971|  6.06k|inline uint8_t *Accessor::GetPointer() {
  972|  6.06k|    if (decodedBuffer)
  ------------------
  |  Branch (972:9): [True: 0, False: 6.06k]
  ------------------
  973|      0|        return decodedBuffer->GetPointer();
  974|       |
  975|  6.06k|    if (sparse)
  ------------------
  |  Branch (975:9): [True: 0, False: 6.06k]
  ------------------
  976|      0|        return sparse->data.data();
  977|       |
  978|  6.06k|    if (!bufferView || !bufferView->buffer) return nullptr;
  ------------------
  |  Branch (978:9): [True: 65, False: 5.99k]
  |  Branch (978:24): [True: 0, False: 5.99k]
  ------------------
  979|  5.99k|    uint8_t *basePtr = bufferView->buffer->GetPointer();
  980|  5.99k|    if (!basePtr) return nullptr;
  ------------------
  |  Branch (980:9): [True: 0, False: 5.99k]
  ------------------
  981|       |
  982|  5.99k|    size_t offset = byteOffset + bufferView->byteOffset;
  983|       |
  984|       |    // Check if region is encoded.
  985|  5.99k|    if (bufferView->buffer->EncodedRegion_Current != nullptr) {
  ------------------
  |  Branch (985:9): [True: 0, False: 5.99k]
  ------------------
  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.99k|    return basePtr + offset;
  994|  5.99k|}
_ZN5glTF28Accessor9GetStrideEv:
  996|  12.9k|inline size_t Accessor::GetStride() {
  997|       |    // Decoded buffer is always packed
  998|  12.9k|    if (decodedBuffer)
  ------------------
  |  Branch (998:9): [True: 0, False: 12.9k]
  ------------------
  999|      0|        return GetElementSize();
 1000|       |
 1001|       |    // Sparse and normal bufferView
 1002|  12.9k|    return (bufferView && bufferView->byteStride ? bufferView->byteStride : GetElementSize());
  ------------------
  |  Branch (1002:13): [True: 12.9k, False: 9]
  |  Branch (1002:27): [True: 3.23k, False: 9.67k]
  ------------------
 1003|  12.9k|}
_ZN5glTF28Accessor14GetMaxByteSizeEv:
 1005|  30.1k|inline size_t Accessor::GetMaxByteSize() {
 1006|  30.1k|    if (decodedBuffer)
  ------------------
  |  Branch (1006:9): [True: 0, False: 30.1k]
  ------------------
 1007|      0|        return decodedBuffer->byteLength;
 1008|       |
 1009|  30.1k|    if (sparse) {
  ------------------
  |  Branch (1009:9): [True: 0, False: 30.1k]
  ------------------
 1010|      0|        return sparse->data.size();
 1011|      0|    }
 1012|       |
 1013|  30.1k|    if (bufferView) {
  ------------------
  |  Branch (1013:9): [True: 30.1k, False: 0]
  ------------------
 1014|  30.1k|        return byteOffset <= bufferView->byteLength ? bufferView->byteLength - byteOffset : 0;
  ------------------
  |  Branch (1014:16): [True: 30.1k, False: 2]
  ------------------
 1015|  30.1k|    }
 1016|       |
 1017|      0|    return 0;
 1018|  30.1k|}
_ZN5glTF25Image4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
 1136|     60|inline void Image::Read(Value &obj, Asset &r) {
 1137|       |    //basisu: no need to handle .ktx2, .basis, load as is
 1138|     60|    if (!mDataLength) {
  ------------------
  |  Branch (1138:9): [True: 60, False: 0]
  ------------------
 1139|     60|        Value *curUri = FindString(obj, "uri");
 1140|     60|        if (nullptr != curUri) {
  ------------------
  |  Branch (1140:13): [True: 0, False: 60]
  ------------------
 1141|      0|            const char *uristr = curUri->GetString();
 1142|       |
 1143|      0|            glTFCommon::Util::DataURI dataURI;
 1144|      0|            if (ParseDataURI(uristr, curUri->GetStringLength(), dataURI)) {
  ------------------
  |  Branch (1144:17): [True: 0, False: 0]
  ------------------
 1145|      0|                mimeType = dataURI.mediaType;
 1146|      0|                if (dataURI.base64) {
  ------------------
  |  Branch (1146:21): [True: 0, False: 0]
  ------------------
 1147|      0|                    uint8_t *ptr = nullptr;
 1148|      0|                    mDataLength = Base64::Decode(dataURI.data, dataURI.dataLength, ptr);
 1149|      0|                    mData.reset(ptr);
 1150|      0|                }
 1151|      0|            } else {
 1152|      0|                this->uri = uristr;
 1153|      0|            }
 1154|     60|        } else if (Value *bufferViewVal = FindUInt(obj, "bufferView")) {
  ------------------
  |  Branch (1154:27): [True: 59, False: 1]
  ------------------
 1155|     59|            this->bufferView = r.bufferViews.Retrieve(bufferViewVal->GetUint());
 1156|     59|            if (Value *mtype = FindString(obj, "mimeType")) {
  ------------------
  |  Branch (1156:24): [True: 57, False: 2]
  ------------------
 1157|     57|                this->mimeType = mtype->GetString();
 1158|     57|            }
 1159|     59|            if (!this->bufferView || this->mimeType.empty()) {
  ------------------
  |  Branch (1159:17): [True: 1, False: 58]
  |  Branch (1159:38): [True: 1, False: 57]
  ------------------
 1160|      1|                throw DeadlyImportError("GLTF2: ", getContextForErrorMessages(id, name), " does not have a URI, so it must have a valid bufferView and mimetype");
 1161|      1|            }
 1162|       |
 1163|     58|            Ref<Buffer> buffer = this->bufferView->buffer;
 1164|       |
 1165|     58|            this->mDataLength = this->bufferView->byteLength;
 1166|       |            // maybe this memcpy could be avoided if aiTexture does not delete[] pcData at destruction.
 1167|       |
 1168|     58|            this->mData.reset(new uint8_t[this->mDataLength]);
 1169|     58|            memcpy(this->mData.get(), buffer->GetPointer() + this->bufferView->byteOffset, this->mDataLength);
 1170|     58|        } else {
 1171|      1|            throw DeadlyImportError("GLTF2: ", getContextForErrorMessages(id, name), " should have either a URI of a bufferView and mimetype");
 1172|      1|        }
 1173|     60|    }
 1174|     60|}
_ZN5glTF25Image9StealDataEv:
 1176|     47|inline uint8_t *Image::StealData() {
 1177|     47|    mDataLength = 0;
 1178|     47|    return mData.release();
 1179|     47|}
_ZN5glTF27Sampler4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
 1199|     58|inline void Sampler::Read(Value &obj, Asset & /*r*/) {
 1200|     58|    SetDefaults();
 1201|       |
 1202|     58|    ReadMember(obj, "name", name);
 1203|     58|    ReadMember(obj, "magFilter", magFilter);
 1204|     58|    ReadMember(obj, "minFilter", minFilter);
 1205|     58|    ReadMember(obj, "wrapS", wrapS);
 1206|     58|    ReadMember(obj, "wrapT", wrapT);
 1207|     58|}
_ZN5glTF27Sampler11SetDefaultsEv:
 1209|    116|inline void Sampler::SetDefaults() {
 1210|       |    //only wrapping modes have defaults
 1211|    116|    wrapS = SamplerWrap::Repeat;
 1212|    116|    wrapT = SamplerWrap::Repeat;
 1213|    116|    magFilter = SamplerMagFilter::UNSET;
 1214|    116|    minFilter = SamplerMinFilter::UNSET;
 1215|    116|}
_ZN5glTF27Texture4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
 1217|     71|inline void Texture::Read(Value &obj, Asset &r) {
 1218|     71|    if (Value *sourceVal = FindUInt(obj, "source")) {
  ------------------
  |  Branch (1218:16): [True: 62, False: 9]
  ------------------
 1219|     62|        source = r.images.Retrieve(sourceVal->GetUint());
 1220|     62|    }
 1221|       |
 1222|     71|    if (Value *samplerVal = FindUInt(obj, "sampler")) {
  ------------------
  |  Branch (1222:16): [True: 60, False: 11]
  ------------------
 1223|     60|        sampler = r.samplers.Retrieve(samplerVal->GetUint());
 1224|     60|    }
 1225|       |
 1226|     71|    if (Value *extensions = FindObject(obj, "extensions")) {
  ------------------
  |  Branch (1226:16): [True: 0, False: 71]
  ------------------
 1227|      0|        if (r.extensionsUsed.KHR_texture_basisu) {
  ------------------
  |  Branch (1227:13): [True: 0, False: 0]
  ------------------
 1228|      0|            if (Value *curBasisU = FindObject(*extensions, "KHR_texture_basisu")) {
  ------------------
  |  Branch (1228:24): [True: 0, False: 0]
  ------------------
 1229|       |
 1230|      0|                if (Value *sourceVal = FindUInt(*curBasisU, "source")) {
  ------------------
  |  Branch (1230:28): [True: 0, False: 0]
  ------------------
 1231|      0|                    source = r.images.Retrieve(sourceVal->GetUint());
 1232|      0|                }
 1233|      0|            }
 1234|      0|        } else if(r.extensionsUsed.EXT_texture_webp) {
  ------------------
  |  Branch (1234:19): [True: 0, False: 0]
  ------------------
 1235|      0|            if (Value *curBasisU = FindObject(*extensions, "EXT_texture_webp")) {
  ------------------
  |  Branch (1235:24): [True: 0, False: 0]
  ------------------
 1236|       |
 1237|      0|                if (Value *sourceVal = FindUInt(*curBasisU, "source")) {
  ------------------
  |  Branch (1237:28): [True: 0, False: 0]
  ------------------
 1238|      0|                    source = r.images.Retrieve(sourceVal->GetUint());
 1239|      0|                }
 1240|      0|            }
 1241|      0|        }
 1242|      0|    }
 1243|     71|}
_ZN5glTF28Material20SetTexturePropertiesERNS_5AssetEPN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEERNS_11TextureInfoE:
 1245|     77|void Material::SetTextureProperties(Asset &r, Value *prop, TextureInfo &out) {
 1246|     77|    if (r.extensionsUsed.KHR_texture_transform) {
  ------------------
  |  Branch (1246:9): [True: 0, False: 77]
  ------------------
 1247|      0|        if (Value *pKHR_texture_transform = FindExtension(*prop, "KHR_texture_transform")) {
  ------------------
  |  Branch (1247:20): [True: 0, False: 0]
  ------------------
 1248|      0|            out.textureTransformSupported = true;
 1249|      0|            if (Value *array = FindArray(*pKHR_texture_transform, "offset")) {
  ------------------
  |  Branch (1249:24): [True: 0, False: 0]
  ------------------
 1250|      0|                out.TextureTransformExt_t.offset[0] = (*array)[0].GetFloat();
 1251|      0|                out.TextureTransformExt_t.offset[1] = (*array)[1].GetFloat();
 1252|      0|            } else {
 1253|      0|                out.TextureTransformExt_t.offset[0] = 0;
 1254|      0|                out.TextureTransformExt_t.offset[1] = 0;
 1255|      0|            }
 1256|       |
 1257|      0|            if (!ReadMember(*pKHR_texture_transform, "rotation", out.TextureTransformExt_t.rotation)) {
  ------------------
  |  Branch (1257:17): [True: 0, False: 0]
  ------------------
 1258|      0|                out.TextureTransformExt_t.rotation = 0;
 1259|      0|            }
 1260|       |
 1261|      0|            if (Value *array = FindArray(*pKHR_texture_transform, "scale")) {
  ------------------
  |  Branch (1261:24): [True: 0, False: 0]
  ------------------
 1262|      0|                out.TextureTransformExt_t.scale[0] = (*array)[0].GetFloat();
 1263|      0|                out.TextureTransformExt_t.scale[1] = (*array)[1].GetFloat();
 1264|      0|            } else {
 1265|      0|                out.TextureTransformExt_t.scale[0] = 1;
 1266|      0|                out.TextureTransformExt_t.scale[1] = 1;
 1267|      0|            }
 1268|      0|        }
 1269|      0|    }
 1270|       |
 1271|     77|    if (Value *indexProp = FindUInt(*prop, "index")) {
  ------------------
  |  Branch (1271:16): [True: 74, False: 3]
  ------------------
 1272|     74|        out.texture = r.textures.Retrieve(indexProp->GetUint());
 1273|     74|    }
 1274|       |
 1275|     77|    if (Value *texcoord = FindUInt(*prop, "texCoord")) {
  ------------------
  |  Branch (1275:16): [True: 0, False: 77]
  ------------------
 1276|      0|        out.texCoord = texcoord->GetUint();
 1277|      0|    }
 1278|     77|}
_ZN5glTF28Material19ReadTexturePropertyERNS_5AssetERN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEEPKcRNS_11TextureInfoE:
 1280|  3.46k|inline void Material::ReadTextureProperty(Asset &r, Value &vals, const char *propName, TextureInfo &out) {
 1281|  3.46k|    if (Value *prop = FindMember(vals, propName)) {
  ------------------
  |  Branch (1281:16): [True: 77, False: 3.39k]
  ------------------
 1282|     77|        SetTextureProperties(r, prop, out);
 1283|     77|    }
 1284|  3.46k|}
_ZN5glTF28Material19ReadTexturePropertyERNS_5AssetERN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEEPKcRNS_17NormalTextureInfoE:
 1286|  1.41k|inline void Material::ReadTextureProperty(Asset &r, Value &vals, const char *propName, NormalTextureInfo &out) {
 1287|  1.41k|    if (Value *prop = FindMember(vals, propName)) {
  ------------------
  |  Branch (1287:16): [True: 0, False: 1.41k]
  ------------------
 1288|      0|        SetTextureProperties(r, prop, out);
 1289|       |
 1290|      0|        if (Value *scale = FindNumber(*prop, "scale")) {
  ------------------
  |  Branch (1290:20): [True: 0, False: 0]
  ------------------
 1291|      0|            out.scale = static_cast<float>(scale->GetDouble());
 1292|      0|        }
 1293|      0|    }
 1294|  1.41k|}
_ZN5glTF28Material19ReadTexturePropertyERNS_5AssetERN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEEPKcRNS_20OcclusionTextureInfoE:
 1296|  1.41k|inline void Material::ReadTextureProperty(Asset &r, Value &vals, const char *propName, OcclusionTextureInfo &out) {
 1297|  1.41k|    if (Value *prop = FindMember(vals, propName)) {
  ------------------
  |  Branch (1297:16): [True: 0, False: 1.41k]
  ------------------
 1298|      0|        SetTextureProperties(r, prop, out);
 1299|       |
 1300|      0|        if (Value *strength = FindNumber(*prop, "strength")) {
  ------------------
  |  Branch (1300:20): [True: 0, False: 0]
  ------------------
 1301|      0|            out.strength = static_cast<float>(strength->GetDouble());
 1302|      0|        }
 1303|      0|    }
 1304|  1.41k|}
_ZN5glTF28Material4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
 1306|  1.42k|inline void Material::Read(Value &material, Asset &r) {
 1307|  1.42k|    SetDefaults();
 1308|       |
 1309|  1.42k|    if (Value *curPbrMetallicRoughness = FindObject(material, "pbrMetallicRoughness")) {
  ------------------
  |  Branch (1309:16): [True: 1.03k, False: 394]
  ------------------
 1310|  1.03k|        ReadMember(*curPbrMetallicRoughness, "baseColorFactor", this->pbrMetallicRoughness.baseColorFactor);
 1311|  1.03k|        ReadTextureProperty(r, *curPbrMetallicRoughness, "baseColorTexture", this->pbrMetallicRoughness.baseColorTexture);
 1312|  1.03k|        ReadTextureProperty(r, *curPbrMetallicRoughness, "metallicRoughnessTexture", this->pbrMetallicRoughness.metallicRoughnessTexture);
 1313|  1.03k|        ReadMember(*curPbrMetallicRoughness, "metallicFactor", this->pbrMetallicRoughness.metallicFactor);
 1314|  1.03k|        ReadMember(*curPbrMetallicRoughness, "roughnessFactor", this->pbrMetallicRoughness.roughnessFactor);
 1315|  1.03k|    }
 1316|       |
 1317|  1.42k|    ReadTextureProperty(r, material, "normalTexture", this->normalTexture);
 1318|  1.42k|    ReadTextureProperty(r, material, "occlusionTexture", this->occlusionTexture);
 1319|  1.42k|    ReadTextureProperty(r, material, "emissiveTexture", this->emissiveTexture);
 1320|  1.42k|    ReadMember(material, "emissiveFactor", this->emissiveFactor);
 1321|       |
 1322|  1.42k|    ReadMember(material, "doubleSided", this->doubleSided);
 1323|  1.42k|    ReadMember(material, "alphaMode", this->alphaMode);
 1324|  1.42k|    ReadMember(material, "alphaCutoff", this->alphaCutoff);
 1325|       |
 1326|  1.42k|    if (Value *extensions = FindObject(material, "extensions")) {
  ------------------
  |  Branch (1326:16): [True: 0, False: 1.42k]
  ------------------
 1327|      0|        if (r.extensionsUsed.KHR_materials_pbrSpecularGlossiness) {
  ------------------
  |  Branch (1327:13): [True: 0, False: 0]
  ------------------
 1328|      0|            if (Value *curPbrSpecularGlossiness = FindObject(*extensions, "KHR_materials_pbrSpecularGlossiness")) {
  ------------------
  |  Branch (1328:24): [True: 0, False: 0]
  ------------------
 1329|      0|                PbrSpecularGlossiness pbrSG;
 1330|       |
 1331|      0|                ReadMember(*curPbrSpecularGlossiness, "diffuseFactor", pbrSG.diffuseFactor);
 1332|      0|                ReadTextureProperty(r, *curPbrSpecularGlossiness, "diffuseTexture", pbrSG.diffuseTexture);
 1333|      0|                ReadTextureProperty(r, *curPbrSpecularGlossiness, "specularGlossinessTexture", pbrSG.specularGlossinessTexture);
 1334|      0|                ReadMember(*curPbrSpecularGlossiness, "specularFactor", pbrSG.specularFactor);
 1335|      0|                ReadMember(*curPbrSpecularGlossiness, "glossinessFactor", pbrSG.glossinessFactor);
 1336|       |
 1337|      0|                this->pbrSpecularGlossiness = Nullable<PbrSpecularGlossiness>(pbrSG);
 1338|      0|            }
 1339|      0|        }
 1340|       |
 1341|      0|        if (r.extensionsUsed.KHR_materials_specular) {
  ------------------
  |  Branch (1341:13): [True: 0, False: 0]
  ------------------
 1342|      0|            if (Value *curMatSpecular = FindObject(*extensions, "KHR_materials_specular")) {
  ------------------
  |  Branch (1342:24): [True: 0, False: 0]
  ------------------
 1343|      0|                MaterialSpecular specular;
 1344|       |
 1345|      0|                ReadMember(*curMatSpecular, "specularFactor", specular.specularFactor);
 1346|      0|                ReadTextureProperty(r, *curMatSpecular, "specularTexture", specular.specularTexture);
 1347|      0|                ReadMember(*curMatSpecular, "specularColorFactor", specular.specularColorFactor);
 1348|      0|                ReadTextureProperty(r, *curMatSpecular, "specularColorTexture", specular.specularColorTexture);
 1349|       |
 1350|      0|                this->materialSpecular = Nullable<MaterialSpecular>(specular);
 1351|      0|            }
 1352|      0|        }
 1353|       |
 1354|       |        // Extension KHR_texture_transform is handled in ReadTextureProperty
 1355|       |
 1356|      0|        if (r.extensionsUsed.KHR_materials_sheen) {
  ------------------
  |  Branch (1356:13): [True: 0, False: 0]
  ------------------
 1357|      0|            if (Value *curMaterialSheen = FindObject(*extensions, "KHR_materials_sheen")) {
  ------------------
  |  Branch (1357:24): [True: 0, False: 0]
  ------------------
 1358|      0|                MaterialSheen sheen;
 1359|       |
 1360|      0|                ReadMember(*curMaterialSheen, "sheenColorFactor", sheen.sheenColorFactor);
 1361|      0|                ReadTextureProperty(r, *curMaterialSheen, "sheenColorTexture", sheen.sheenColorTexture);
 1362|      0|                ReadMember(*curMaterialSheen, "sheenRoughnessFactor", sheen.sheenRoughnessFactor);
 1363|      0|                ReadTextureProperty(r, *curMaterialSheen, "sheenRoughnessTexture", sheen.sheenRoughnessTexture);
 1364|       |
 1365|      0|                this->materialSheen = Nullable<MaterialSheen>(sheen);
 1366|      0|            }
 1367|      0|        }
 1368|       |
 1369|      0|        if (r.extensionsUsed.KHR_materials_clearcoat) {
  ------------------
  |  Branch (1369:13): [True: 0, False: 0]
  ------------------
 1370|      0|            if (Value *curMaterialClearcoat = FindObject(*extensions, "KHR_materials_clearcoat")) {
  ------------------
  |  Branch (1370:24): [True: 0, False: 0]
  ------------------
 1371|      0|                MaterialClearcoat clearcoat;
 1372|       |
 1373|      0|                ReadMember(*curMaterialClearcoat, "clearcoatFactor", clearcoat.clearcoatFactor);
 1374|      0|                ReadTextureProperty(r, *curMaterialClearcoat, "clearcoatTexture", clearcoat.clearcoatTexture);
 1375|      0|                ReadMember(*curMaterialClearcoat, "clearcoatRoughnessFactor", clearcoat.clearcoatRoughnessFactor);
 1376|      0|                ReadTextureProperty(r, *curMaterialClearcoat, "clearcoatRoughnessTexture", clearcoat.clearcoatRoughnessTexture);
 1377|      0|                ReadTextureProperty(r, *curMaterialClearcoat, "clearcoatNormalTexture", clearcoat.clearcoatNormalTexture);
 1378|       |
 1379|      0|                this->materialClearcoat = Nullable<MaterialClearcoat>(clearcoat);
 1380|      0|            }
 1381|      0|        }
 1382|       |
 1383|      0|        if (r.extensionsUsed.KHR_materials_transmission) {
  ------------------
  |  Branch (1383:13): [True: 0, False: 0]
  ------------------
 1384|      0|            if (Value *curMaterialTransmission = FindObject(*extensions, "KHR_materials_transmission")) {
  ------------------
  |  Branch (1384:24): [True: 0, False: 0]
  ------------------
 1385|      0|                MaterialTransmission transmission;
 1386|       |
 1387|      0|                ReadMember(*curMaterialTransmission, "transmissionFactor", transmission.transmissionFactor);
 1388|      0|                ReadTextureProperty(r, *curMaterialTransmission, "transmissionTexture", transmission.transmissionTexture);
 1389|       |
 1390|      0|                this->materialTransmission = Nullable<MaterialTransmission>(transmission);
 1391|      0|            }
 1392|      0|        }
 1393|       |
 1394|      0|        if (r.extensionsUsed.KHR_materials_volume) {
  ------------------
  |  Branch (1394:13): [True: 0, False: 0]
  ------------------
 1395|      0|            if (Value *curMaterialVolume = FindObject(*extensions, "KHR_materials_volume")) {
  ------------------
  |  Branch (1395:24): [True: 0, False: 0]
  ------------------
 1396|      0|                MaterialVolume volume;
 1397|       |
 1398|      0|                ReadMember(*curMaterialVolume, "thicknessFactor", volume.thicknessFactor);
 1399|      0|                ReadTextureProperty(r, *curMaterialVolume, "thicknessTexture", volume.thicknessTexture);
 1400|      0|                ReadMember(*curMaterialVolume, "attenuationDistance", volume.attenuationDistance);
 1401|      0|                ReadMember(*curMaterialVolume, "attenuationColor", volume.attenuationColor);
 1402|       |
 1403|      0|                this->materialVolume = Nullable<MaterialVolume>(volume);
 1404|      0|            }
 1405|      0|        }
 1406|       |
 1407|      0|        if (r.extensionsUsed.KHR_materials_ior) {
  ------------------
  |  Branch (1407:13): [True: 0, False: 0]
  ------------------
 1408|      0|            if (Value *curMaterialIOR = FindObject(*extensions, "KHR_materials_ior")) {
  ------------------
  |  Branch (1408:24): [True: 0, False: 0]
  ------------------
 1409|      0|                MaterialIOR ior;
 1410|       |
 1411|      0|                ReadMember(*curMaterialIOR, "ior", ior.ior);
 1412|       |
 1413|      0|                this->materialIOR = Nullable<MaterialIOR>(ior);
 1414|      0|            }
 1415|      0|        }
 1416|       |
 1417|      0|        if (r.extensionsUsed.KHR_materials_emissive_strength) {
  ------------------
  |  Branch (1417:13): [True: 0, False: 0]
  ------------------
 1418|      0|            if (Value *curMaterialEmissiveStrength = FindObject(*extensions, "KHR_materials_emissive_strength")) {
  ------------------
  |  Branch (1418:24): [True: 0, False: 0]
  ------------------
 1419|      0|                MaterialEmissiveStrength emissiveStrength;
 1420|       |
 1421|      0|                ReadMember(*curMaterialEmissiveStrength, "emissiveStrength", emissiveStrength.emissiveStrength);
 1422|       |
 1423|      0|                this->materialEmissiveStrength = Nullable<MaterialEmissiveStrength>(emissiveStrength);
 1424|      0|            }
 1425|      0|        }
 1426|       |
 1427|      0|        if (r.extensionsUsed.KHR_materials_anisotropy) {
  ------------------
  |  Branch (1427:13): [True: 0, False: 0]
  ------------------
 1428|      0|            if (Value *curMaterialAnisotropy = FindObject(*extensions, "KHR_materials_anisotropy")) {
  ------------------
  |  Branch (1428:24): [True: 0, False: 0]
  ------------------
 1429|      0|                MaterialAnisotropy anisotropy;
 1430|       |
 1431|      0|                ReadMember(*curMaterialAnisotropy, "anisotropyStrength", anisotropy.anisotropyStrength);
 1432|      0|                ReadMember(*curMaterialAnisotropy, "anisotropyRotation", anisotropy.anisotropyRotation);
 1433|      0|                ReadTextureProperty(r, *curMaterialAnisotropy, "anisotropyTexture", anisotropy.anisotropyTexture);
 1434|       |
 1435|      0|                this->materialAnisotropy = Nullable<MaterialAnisotropy>(anisotropy);
 1436|      0|            }
 1437|      0|        }
 1438|       |
 1439|      0|        unlit = nullptr != FindObject(*extensions, "KHR_materials_unlit");
 1440|      0|    }
 1441|  1.42k|}
_ZN5glTF28Material11SetDefaultsEv:
 1443|  4.65k|inline void Material::SetDefaults() {
 1444|       |    //pbr materials
 1445|  4.65k|    SetVector(pbrMetallicRoughness.baseColorFactor, defaultBaseColor);
 1446|  4.65k|    pbrMetallicRoughness.metallicFactor = 1.0f;
 1447|  4.65k|    pbrMetallicRoughness.roughnessFactor = 1.0f;
 1448|       |
 1449|  4.65k|    SetVector(emissiveFactor, defaultEmissiveFactor);
 1450|  4.65k|    alphaMode = "OPAQUE";
 1451|  4.65k|    alphaCutoff = 0.5f;
 1452|  4.65k|    doubleSided = false;
 1453|  4.65k|    unlit = false;
 1454|  4.65k|}
_ZN5glTF221PbrSpecularGlossiness11SetDefaultsEv:
 1456|  3.23k|inline void PbrSpecularGlossiness::SetDefaults() {
 1457|       |    //pbrSpecularGlossiness properties
 1458|  3.23k|    SetVector(diffuseFactor, defaultDiffuseFactor);
 1459|  3.23k|    SetVector(specularFactor, defaultSpecularFactor);
 1460|  3.23k|    glossinessFactor = 1.0f;
 1461|  3.23k|}
_ZN5glTF216MaterialSpecular11SetDefaultsEv:
 1463|  3.23k|inline void MaterialSpecular::SetDefaults() {
 1464|       |    //KHR_materials_specular properties
 1465|  3.23k|    SetVector(specularColorFactor, defaultSpecularColorFactor);
 1466|  3.23k|    specularFactor = 1.f;
 1467|  3.23k|}
_ZN5glTF213MaterialSheen11SetDefaultsEv:
 1469|  3.23k|inline void MaterialSheen::SetDefaults() {
 1470|       |    //KHR_materials_sheen properties
 1471|  3.23k|    SetVector(sheenColorFactor, defaultSheenFactor);
 1472|  3.23k|    sheenRoughnessFactor = 0.f;
 1473|  3.23k|}
_ZN5glTF214MaterialVolume11SetDefaultsEv:
 1475|  3.23k|inline void MaterialVolume::SetDefaults() {
 1476|       |    //KHR_materials_volume properties
 1477|  3.23k|    thicknessFactor = 0.f;
 1478|  3.23k|    attenuationDistance = std::numeric_limits<float>::infinity();
 1479|  3.23k|    SetVector(attenuationColor, defaultAttenuationColor);
 1480|  3.23k|}
_ZN5glTF211MaterialIOR11SetDefaultsEv:
 1482|  3.23k|inline void MaterialIOR::SetDefaults() {
 1483|       |    //KHR_materials_ior properties
 1484|  3.23k|    ior = 1.5f;
 1485|  3.23k|}
_ZN5glTF224MaterialEmissiveStrength11SetDefaultsEv:
 1487|  3.23k|inline void MaterialEmissiveStrength::SetDefaults() {
 1488|       |    //KHR_materials_emissive_strength properties
 1489|  3.23k|    emissiveStrength = 0.f;
 1490|  3.23k|}
_ZN5glTF218MaterialAnisotropy11SetDefaultsEv:
 1492|  3.23k|inline void MaterialAnisotropy::SetDefaults() {
 1493|       |    //KHR_materials_anisotropy properties
 1494|  3.23k|    anisotropyStrength = 0.f;
 1495|  3.23k|    anisotropyRotation = 0.f;
 1496|  3.23k|}
_ZN5glTF24Mesh4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
 1498|  1.79k|inline void Mesh::Read(Value &pJSON_Object, Asset &pAsset_Root) {
 1499|  1.79k|    Value *curName = FindMember(pJSON_Object, "name");
 1500|  1.79k|    if (nullptr != curName && curName->IsString()) {
  ------------------
  |  Branch (1500:9): [True: 1.50k, False: 289]
  |  Branch (1500:31): [True: 1.50k, False: 1]
  ------------------
 1501|  1.50k|        name = curName->GetString();
 1502|  1.50k|    }
 1503|       |
 1504|       |    /****************** Mesh primitives ******************/
 1505|  1.79k|    Value *curPrimitives = FindArray(pJSON_Object, "primitives");
 1506|  1.79k|    if (nullptr != curPrimitives) {
  ------------------
  |  Branch (1506:9): [True: 1.76k, False: 27]
  ------------------
 1507|  1.76k|        this->primitives.resize(curPrimitives->Size());
 1508|  3.52k|        for (unsigned int i = 0; i < curPrimitives->Size(); ++i) {
  ------------------
  |  Branch (1508:34): [True: 1.77k, False: 1.74k]
  ------------------
 1509|  1.77k|            Value &primitive = (*curPrimitives)[i];
 1510|       |
 1511|  1.77k|            Primitive &prim = this->primitives[i];
 1512|  1.77k|            prim.mode = MemberOrDefault(primitive, "mode", PrimitiveMode_TRIANGLES);
 1513|       |
 1514|  1.77k|            if (Value *indices = FindUInt(primitive, "indices")) {
  ------------------
  |  Branch (1514:24): [True: 1.08k, False: 694]
  ------------------
 1515|  1.08k|                prim.indices = pAsset_Root.accessors.Retrieve(indices->GetUint());
 1516|  1.08k|            }
 1517|       |
 1518|  1.77k|            if (Value *material = FindUInt(primitive, "material")) {
  ------------------
  |  Branch (1518:24): [True: 1.43k, False: 346]
  ------------------
 1519|  1.43k|                prim.material = pAsset_Root.materials.Retrieve(material->GetUint());
 1520|  1.43k|            }
 1521|       |
 1522|  1.77k|            if (Value *attrs = FindObject(primitive, "attributes")) {
  ------------------
  |  Branch (1522:24): [True: 1.66k, False: 115]
  ------------------
 1523|  8.00k|                for (Value::MemberIterator it = attrs->MemberBegin(); it != attrs->MemberEnd(); ++it) {
  ------------------
  |  Branch (1523:71): [True: 6.36k, False: 1.64k]
  ------------------
 1524|  6.36k|                    if (!it->value.IsUint()) continue;
  ------------------
  |  Branch (1524:25): [True: 9, False: 6.35k]
  ------------------
 1525|  6.35k|                    const char *attr = it->name.GetString();
 1526|       |                    // Valid attribute semantics include POSITION, NORMAL, TANGENT, TEXCOORD, COLOR, JOINT, JOINTMATRIX,
 1527|       |                    // and WEIGHT.Attribute semantics can be of the form[semantic]_[set_index], e.g., TEXCOORD_0, TEXCOORD_1, etc.
 1528|       |
 1529|  6.35k|                    int undPos = 0;
 1530|  6.35k|                    Mesh::AccessorList *vec = nullptr;
 1531|  6.35k|                    if (GetAttribVector(prim, attr, vec, undPos)) {
  ------------------
  |  Branch (1531:25): [True: 5.89k, False: 458]
  ------------------
 1532|  5.89k|                        size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0;
  ------------------
  |  Branch (1532:38): [True: 2.92k, False: 2.97k]
  ------------------
 1533|  5.89k|                        if ((*vec).size() != idx) {
  ------------------
  |  Branch (1533:29): [True: 22, False: 5.87k]
  ------------------
 1534|     22|                            throw DeadlyImportError("GLTF: Invalid attribute in mesh: ", name, " primitive: ", i, "attrib: ", attr,
 1535|     22|                                    ". All indices for indexed attribute semantics must start with 0 and be continuous positive integers: TEXCOORD_0, TEXCOORD_1, etc.");
 1536|     22|                        }
 1537|  5.87k|                        (*vec).resize(idx + 1);
 1538|  5.87k|                        (*vec)[idx] = pAsset_Root.accessors.Retrieve(it->value.GetUint());
 1539|  5.87k|                    }
 1540|  6.35k|                }
 1541|  1.66k|            }
 1542|       |
 1543|       |#ifdef ASSIMP_ENABLE_DRACO
 1544|       |            // KHR_draco_mesh_compression spec: Draco can only be used for glTF Triangles or Triangle Strips
 1545|       |            if (pAsset_Root.extensionsUsed.KHR_draco_mesh_compression && (prim.mode == PrimitiveMode_TRIANGLES || prim.mode == PrimitiveMode_TRIANGLE_STRIP)) {
 1546|       |                // Look for draco mesh compression extension and bufferView
 1547|       |                // Skip if any missing
 1548|       |                if (Value *dracoExt = FindExtension(primitive, "KHR_draco_mesh_compression")) {
 1549|       |                    if (Value *bufView = FindUInt(*dracoExt, "bufferView")) {
 1550|       |                        // Attempt to load indices and attributes using draco compression
 1551|       |                        auto bufferView = pAsset_Root.bufferViews.Retrieve(bufView->GetUint());
 1552|       |                        // Attempt to perform the draco decode on the buffer data
 1553|       |                        const char *bufferViewData = reinterpret_cast<const char *>(bufferView->buffer->GetPointer() + bufferView->byteOffset);
 1554|       |                        draco::DecoderBuffer decoderBuffer;
 1555|       |                        decoderBuffer.Init(bufferViewData, bufferView->byteLength);
 1556|       |                        draco::Decoder decoder;
 1557|       |                        auto decodeResult = decoder.DecodeMeshFromBuffer(&decoderBuffer);
 1558|       |                        if (!decodeResult.ok()) {
 1559|       |                            // A corrupt Draco isn't actually fatal if the primitive data is also provided in a standard buffer, but does anyone do that?
 1560|       |                            throw DeadlyImportError("GLTF: Invalid Draco mesh compression in mesh: ", name, " primitive: ", i, ": ", decodeResult.status().error_msg_string());
 1561|       |                        }
 1562|       |
 1563|       |                        // Now we have a draco mesh
 1564|       |                        const std::unique_ptr<draco::Mesh> &pDracoMesh = decodeResult.value();
 1565|       |
 1566|       |                        // Redirect the accessors to the decoded data
 1567|       |
 1568|       |                        // Indices
 1569|       |                        SetDecodedIndexBuffer_Draco(*pDracoMesh, prim);
 1570|       |
 1571|       |                        // Vertex attributes
 1572|       |                        if (Value *attrs = FindObject(*dracoExt, "attributes")) {
 1573|       |                            for (Value::MemberIterator it = attrs->MemberBegin(); it != attrs->MemberEnd(); ++it) {
 1574|       |                                if (!it->value.IsUint()) continue;
 1575|       |                                const char *attr = it->name.GetString();
 1576|       |
 1577|       |                                int undPos = 0;
 1578|       |                                Mesh::AccessorList *vec = nullptr;
 1579|       |                                if (GetAttribVector(prim, attr, vec, undPos)) {
 1580|       |                                    size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0;
 1581|       |                                    if (idx >= (*vec).size()) {
 1582|       |                                        throw DeadlyImportError("GLTF: Invalid draco attribute in mesh: ", name, " primitive: ", i, " attrib: ", attr,
 1583|       |                                                ". All indices for indexed attribute semantics must start with 0 and be continuous positive integers: TEXCOORD_0, TEXCOORD_1, etc.");
 1584|       |                                    }
 1585|       |
 1586|       |                                    if (!(*vec)[idx]) {
 1587|       |                                        throw DeadlyImportError("GLTF: Invalid draco attribute in mesh: ", name, " primitive: ", i, " attrib: ", attr,
 1588|       |                                                ". All draco-encoded attributes must also define an accessor.");
 1589|       |                                    }
 1590|       |
 1591|       |                                    Accessor &attribAccessor = *(*vec)[idx];
 1592|       |                                    if (attribAccessor.count == 0)
 1593|       |                                        throw DeadlyImportError("GLTF: Invalid draco attribute in mesh: ", name, " primitive: ", i, " attrib: ", attr);
 1594|       |
 1595|       |                                    // Redirect this accessor to the appropriate Draco vertex attribute data
 1596|       |                                    const uint32_t dracoAttribId = it->value.GetUint();
 1597|       |                                    SetDecodedAttributeBuffer_Draco(*pDracoMesh, dracoAttribId, attribAccessor);
 1598|       |                                }
 1599|       |                            }
 1600|       |                        }
 1601|       |                    }
 1602|       |                }
 1603|       |            }
 1604|       |#endif
 1605|       |
 1606|  1.75k|            Value *targetsArray = FindArray(primitive, "targets");
 1607|  1.75k|            if (nullptr != targetsArray) {
  ------------------
  |  Branch (1607:17): [True: 0, False: 1.75k]
  ------------------
 1608|      0|                prim.targets.resize(targetsArray->Size());
 1609|      0|                for (unsigned int j = 0; j < targetsArray->Size(); ++j) {
  ------------------
  |  Branch (1609:42): [True: 0, False: 0]
  ------------------
 1610|      0|                    Value &target = (*targetsArray)[j];
 1611|      0|                    if (!target.IsObject()) {
  ------------------
  |  Branch (1611:25): [True: 0, False: 0]
  ------------------
 1612|      0|                        continue;
 1613|      0|                    }
 1614|      0|                    for (Value::MemberIterator it = target.MemberBegin(); it != target.MemberEnd(); ++it) {
  ------------------
  |  Branch (1614:75): [True: 0, False: 0]
  ------------------
 1615|      0|                        if (!it->value.IsUint()) {
  ------------------
  |  Branch (1615:29): [True: 0, False: 0]
  ------------------
 1616|      0|                            continue;
 1617|      0|                        }
 1618|      0|                        const char *attr = it->name.GetString();
 1619|       |                        // Valid attribute semantics include POSITION, NORMAL, TANGENT
 1620|      0|                        int undPos = 0;
 1621|      0|                        Mesh::AccessorList *vec = nullptr;
 1622|      0|                        if (GetAttribTargetVector(prim, j, attr, vec, undPos)) {
  ------------------
  |  Branch (1622:29): [True: 0, False: 0]
  ------------------
 1623|      0|                            size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0;
  ------------------
  |  Branch (1623:42): [True: 0, False: 0]
  ------------------
 1624|      0|                            if ((*vec).size() <= idx) {
  ------------------
  |  Branch (1624:33): [True: 0, False: 0]
  ------------------
 1625|      0|                                (*vec).resize(idx + 1);
 1626|      0|                            }
 1627|      0|                            (*vec)[idx] = pAsset_Root.accessors.Retrieve(it->value.GetUint());
 1628|      0|                        }
 1629|      0|                    }
 1630|      0|                }
 1631|      0|            }
 1632|       |
 1633|  1.75k|            if(this->targetNames.empty())
  ------------------
  |  Branch (1633:16): [True: 1.60k, False: 157]
  ------------------
 1634|  1.60k|            {
 1635|  1.60k|                Value *curExtras = FindObject(primitive, "extras");
 1636|  1.60k|                if (nullptr != curExtras) {
  ------------------
  |  Branch (1636:21): [True: 0, False: 1.60k]
  ------------------
 1637|      0|                    if (Value *curTargetNames = FindArray(*curExtras, "targetNames")) {
  ------------------
  |  Branch (1637:32): [True: 0, False: 0]
  ------------------
 1638|      0|                        this->targetNames.resize(curTargetNames->Size());
 1639|      0|                        for (unsigned int j = 0; j < curTargetNames->Size(); ++j) {
  ------------------
  |  Branch (1639:50): [True: 0, False: 0]
  ------------------
 1640|      0|                            Value &targetNameValue = (*curTargetNames)[j];
 1641|      0|                            if (targetNameValue.IsString()) {
  ------------------
  |  Branch (1641:33): [True: 0, False: 0]
  ------------------
 1642|      0|                                this->targetNames[j] = targetNameValue.GetString();
 1643|      0|                            }
 1644|      0|                        }
 1645|      0|                    }
 1646|      0|                }
 1647|  1.60k|            }
 1648|  1.75k|        }
 1649|  1.76k|    }
 1650|       |
 1651|  1.76k|    Value *curWeights = FindArray(pJSON_Object, "weights");
 1652|  1.76k|    if (nullptr != curWeights) {
  ------------------
  |  Branch (1652:9): [True: 0, False: 1.76k]
  ------------------
 1653|      0|        this->weights.resize(curWeights->Size());
 1654|      0|        for (unsigned int i = 0; i < curWeights->Size(); ++i) {
  ------------------
  |  Branch (1654:34): [True: 0, False: 0]
  ------------------
 1655|      0|            Value &weightValue = (*curWeights)[i];
 1656|      0|            if (weightValue.IsNumber()) {
  ------------------
  |  Branch (1656:17): [True: 0, False: 0]
  ------------------
 1657|      0|                this->weights[i] = weightValue.GetFloat();
 1658|      0|            }
 1659|      0|        }
 1660|      0|    }
 1661|       |
 1662|  1.76k|    Value *curExtras = FindObject(pJSON_Object, "extras");
 1663|  1.76k|    if (nullptr != curExtras) {
  ------------------
  |  Branch (1663:9): [True: 0, False: 1.76k]
  ------------------
 1664|      0|        if (Value *curTargetNames = FindArray(*curExtras, "targetNames")) {
  ------------------
  |  Branch (1664:20): [True: 0, False: 0]
  ------------------
 1665|      0|            this->targetNames.resize(curTargetNames->Size());
 1666|      0|            for (unsigned int i = 0; i < curTargetNames->Size(); ++i) {
  ------------------
  |  Branch (1666:38): [True: 0, False: 0]
  ------------------
 1667|      0|                Value &targetNameValue = (*curTargetNames)[i];
 1668|      0|                if (targetNameValue.IsString()) {
  ------------------
  |  Branch (1668:21): [True: 0, False: 0]
  ------------------
 1669|      0|                    this->targetNames[i] = targetNameValue.GetString();
 1670|      0|                }
 1671|      0|            }
 1672|      0|        }
 1673|      0|    }
 1674|  1.76k|}
_ZN5glTF24Node4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
 1733|  11.8k|inline void Node::Read(Value &obj, Asset &r) {
 1734|  11.8k|    if (name.empty()) {
  ------------------
  |  Branch (1734:9): [True: 928, False: 10.9k]
  ------------------
 1735|    928|        name = id;
 1736|    928|    }
 1737|       |
 1738|  11.8k|    Value *curChildren = FindArray(obj, "children");
 1739|  11.8k|    if (nullptr != curChildren) {
  ------------------
  |  Branch (1739:9): [True: 5.94k, False: 5.92k]
  ------------------
 1740|  5.94k|        this->children.reserve(curChildren->Size());
 1741|  15.2k|        for (unsigned int i = 0; i < curChildren->Size(); ++i) {
  ------------------
  |  Branch (1741:34): [True: 9.31k, False: 5.94k]
  ------------------
 1742|  9.31k|            Value &child = (*curChildren)[i];
 1743|  9.31k|            if (child.IsUint()) {
  ------------------
  |  Branch (1743:17): [True: 9.26k, False: 50]
  ------------------
 1744|       |                // get/create the child node
 1745|  9.26k|                Ref<Node> chn = r.nodes.Retrieve(child.GetUint());
 1746|  9.26k|                if (chn) {
  ------------------
  |  Branch (1746:21): [True: 8.97k, False: 291]
  ------------------
 1747|  8.97k|                    this->children.push_back(chn);
 1748|  8.97k|                }
 1749|  9.26k|            }
 1750|  9.31k|        }
 1751|  5.94k|    }
 1752|       |
 1753|  11.8k|    Value *curMatrix = FindArray(obj, "matrix");
 1754|  11.8k|    if (nullptr != curMatrix) {
  ------------------
  |  Branch (1754:9): [True: 9.62k, False: 2.24k]
  ------------------
 1755|  9.62k|        ReadValue(*curMatrix, this->matrix);
 1756|  9.62k|    } else {
 1757|  2.24k|        ReadMember(obj, "translation", translation);
 1758|  2.24k|        ReadMember(obj, "scale", scale);
 1759|  2.24k|        ReadMember(obj, "rotation", rotation);
 1760|  2.24k|    }
 1761|       |
 1762|  11.8k|    Value *curMesh = FindUInt(obj, "mesh");
 1763|  11.8k|    if (nullptr != curMesh) {
  ------------------
  |  Branch (1763:9): [True: 1.80k, False: 10.0k]
  ------------------
 1764|  1.80k|        unsigned int numMeshes = 1;
 1765|  1.80k|        this->meshes.reserve(numMeshes);
 1766|  1.80k|        Ref<Mesh> meshRef = r.meshes.Retrieve((*curMesh).GetUint());
 1767|  1.80k|        if (meshRef) {
  ------------------
  |  Branch (1767:13): [True: 1.61k, False: 194]
  ------------------
 1768|  1.61k|            this->meshes.push_back(meshRef);
 1769|  1.61k|        }
 1770|  1.80k|    }
 1771|       |
 1772|       |    // Do not retrieve a skin here, just take a reference, to avoid infinite recursion
 1773|       |    // Skins will be properly loaded later
 1774|  11.8k|    Value *curSkin = FindUInt(obj, "skin");
 1775|  11.8k|    if (nullptr != curSkin) {
  ------------------
  |  Branch (1775:9): [True: 351, False: 11.5k]
  ------------------
 1776|    351|        this->skin = r.skins.Get(curSkin->GetUint());
 1777|    351|    }
 1778|       |
 1779|  11.8k|    Value *curCamera = FindUInt(obj, "camera");
 1780|  11.8k|    if (nullptr != curCamera) {
  ------------------
  |  Branch (1780:9): [True: 0, False: 11.8k]
  ------------------
 1781|      0|        this->camera = r.cameras.Retrieve(curCamera->GetUint());
 1782|      0|        if (this->camera) {
  ------------------
  |  Branch (1782:13): [True: 0, False: 0]
  ------------------
 1783|      0|            this->camera->id = this->id;
 1784|      0|        }
 1785|      0|    }
 1786|       |
 1787|  11.8k|    Value *curExtensions = FindObject(obj, "extensions");
 1788|  11.8k|    if (nullptr != curExtensions) {
  ------------------
  |  Branch (1788:9): [True: 0, False: 11.8k]
  ------------------
 1789|      0|        if (r.extensionsUsed.KHR_lights_punctual) {
  ------------------
  |  Branch (1789:13): [True: 0, False: 0]
  ------------------
 1790|      0|            if (Value *ext = FindObject(*curExtensions, "KHR_lights_punctual")) {
  ------------------
  |  Branch (1790:24): [True: 0, False: 0]
  ------------------
 1791|      0|                Value *curLight = FindUInt(*ext, "light");
 1792|      0|                if (nullptr != curLight) {
  ------------------
  |  Branch (1792:21): [True: 0, False: 0]
  ------------------
 1793|      0|                    this->light = r.lights.Retrieve(curLight->GetUint());
 1794|      0|                    if (this->light) {
  ------------------
  |  Branch (1794:25): [True: 0, False: 0]
  ------------------
 1795|      0|                        this->light->id = this->id;
 1796|      0|                    }
 1797|      0|                }
 1798|      0|            }
 1799|      0|        }
 1800|      0|    }
 1801|  11.8k|}
_ZN5glTF25Scene4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
 1803|  1.98k|inline void Scene::Read(Value &obj, Asset &r) {
 1804|  1.98k|    if (Value *scene_name = FindString(obj, "name")) {
  ------------------
  |  Branch (1804:16): [True: 4, False: 1.98k]
  ------------------
 1805|      4|        if (scene_name->IsString()) {
  ------------------
  |  Branch (1805:13): [True: 4, False: 0]
  ------------------
 1806|      4|            this->name = scene_name->GetString();
 1807|      4|        }
 1808|      4|    }
 1809|  1.98k|    if (Value *array = FindArray(obj, "nodes")) {
  ------------------
  |  Branch (1809:16): [True: 1.96k, False: 23]
  ------------------
 1810|  4.10k|        for (unsigned int i = 0; i < array->Size(); ++i) {
  ------------------
  |  Branch (1810:34): [True: 2.14k, False: 1.96k]
  ------------------
 1811|  2.14k|            if (!(*array)[i].IsUint()) continue;
  ------------------
  |  Branch (1811:17): [True: 42, False: 2.09k]
  ------------------
 1812|  2.09k|            Ref<Node> node = r.nodes.Retrieve((*array)[i].GetUint());
 1813|  2.09k|            if (node)
  ------------------
  |  Branch (1813:17): [True: 1.84k, False: 252]
  ------------------
 1814|  1.84k|                this->nodes.push_back(node);
 1815|  2.09k|        }
 1816|  1.96k|    }
 1817|  1.98k|}
_ZN5glTF24Skin4ReadERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEERNS_5AssetE:
 1819|    389|inline void Skin::Read(Value &obj, Asset &r) {
 1820|    389|    if (Value *matrices = FindUInt(obj, "inverseBindMatrices")) {
  ------------------
  |  Branch (1820:16): [True: 367, False: 22]
  ------------------
 1821|    367|        inverseBindMatrices = r.accessors.Retrieve(matrices->GetUint());
 1822|    367|    }
 1823|       |
 1824|    389|    if (Value *joints = FindArray(obj, "joints")) {
  ------------------
  |  Branch (1824:16): [True: 356, False: 33]
  ------------------
 1825|  3.85k|        for (unsigned i = 0; i < joints->Size(); ++i) {
  ------------------
  |  Branch (1825:30): [True: 3.49k, False: 356]
  ------------------
 1826|  3.49k|            if (!(*joints)[i].IsUint()) continue;
  ------------------
  |  Branch (1826:17): [True: 29, False: 3.46k]
  ------------------
 1827|  3.46k|            Ref<Node> node = r.nodes.Retrieve((*joints)[i].GetUint());
 1828|  3.46k|            if (node) {
  ------------------
  |  Branch (1828:17): [True: 3.45k, False: 9]
  ------------------
 1829|  3.45k|                this->jointNames.push_back(node);
 1830|  3.45k|            }
 1831|  3.46k|        }
 1832|    356|    }
 1833|    389|}
_ZN5glTF213AssetMetadata4ReadERN9rapidjson15GenericDocumentINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEES6_EE:
 1896|  4.50k|inline void AssetMetadata::Read(Document &doc) {
 1897|  4.50k|    if (Value *obj = FindObject(doc, "asset")) {
  ------------------
  |  Branch (1897:16): [True: 4.04k, False: 453]
  ------------------
 1898|  4.04k|        ReadMember(*obj, "copyright", copyright);
 1899|  4.04k|        ReadMember(*obj, "generator", generator);
 1900|       |
 1901|  4.04k|        if (Value *versionString = FindStringInContext(*obj, "version", "\"asset\"")) {
  ------------------
  |  Branch (1901:20): [True: 3.80k, False: 245]
  ------------------
 1902|  3.80k|            version = versionString->GetString();
 1903|  3.80k|        }
 1904|  4.04k|        Value *curProfile = FindObjectInContext(*obj, "profile", "\"asset\"");
 1905|  4.04k|        if (nullptr != curProfile) {
  ------------------
  |  Branch (1905:13): [True: 0, False: 4.04k]
  ------------------
 1906|      0|            ReadMember(*curProfile, "api", this->profile.api);
 1907|      0|            ReadMember(*curProfile, "version", this->profile.version);
 1908|      0|        }
 1909|  4.04k|    }
 1910|       |
 1911|  4.50k|    if (version.empty() || version[0] != '2') {
  ------------------
  |  Branch (1911:9): [True: 154, False: 4.34k]
  |  Branch (1911:28): [True: 66, False: 4.28k]
  ------------------
 1912|    212|        throw DeadlyImportError("GLTF: Unsupported glTF version: ", version);
 1913|    212|    }
 1914|  4.50k|}
_ZN5glTF25Asset16ReadBinaryHeaderERN6Assimp8IOStreamERNSt3__16vectorIcNS4_9allocatorIcEEEE:
 1920|  4.22k|inline void Asset::ReadBinaryHeader(IOStream &stream, std::vector<char> &sceneData) {
 1921|  4.22k|    ASSIMP_LOG_DEBUG("Reading GLTF2 binary");
 1922|  4.22k|    GLB_Header header;
 1923|  4.22k|    if (stream.Read(&header, sizeof(header), 1) != 1) {
  ------------------
  |  Branch (1923:9): [True: 0, False: 4.22k]
  ------------------
 1924|      0|        throw DeadlyImportError("GLTF: Unable to read the file header");
 1925|      0|    }
 1926|       |
 1927|  4.22k|    if (strncmp((char *)header.magic, AI_GLB_MAGIC_NUMBER, sizeof(header.magic)) != 0) {
  ------------------
  |  |  147|  4.22k|#define AI_GLB_MAGIC_NUMBER "glTF"
  ------------------
  |  Branch (1927:9): [True: 0, False: 4.22k]
  ------------------
 1928|      0|        throw DeadlyImportError("GLTF: Invalid binary glTF file");
 1929|      0|    }
 1930|       |
 1931|  4.22k|    AI_SWAP4(header.version);
 1932|  4.22k|    asset.version = ai_to_string(header.version);
 1933|  4.22k|    if (header.version != 2) {
  ------------------
  |  Branch (1933:9): [True: 178, False: 4.04k]
  ------------------
 1934|    178|        throw DeadlyImportError("GLTF: Unsupported binary glTF version");
 1935|    178|    }
 1936|       |
 1937|  4.04k|    GLB_Chunk chunk;
 1938|  4.04k|    if (stream.Read(&chunk, sizeof(chunk), 1) != 1) {
  ------------------
  |  Branch (1938:9): [True: 0, False: 4.04k]
  ------------------
 1939|      0|        throw DeadlyImportError("GLTF: Unable to read JSON chunk");
 1940|      0|    }
 1941|       |
 1942|  4.04k|    AI_SWAP4(chunk.chunkLength);
 1943|  4.04k|    AI_SWAP4(chunk.chunkType);
 1944|       |
 1945|  4.04k|    if (chunk.chunkType != ChunkType_JSON) {
  ------------------
  |  Branch (1945:9): [True: 16, False: 4.02k]
  ------------------
 1946|     16|        throw DeadlyImportError("GLTF: JSON chunk missing");
 1947|     16|    }
 1948|       |
 1949|       |    // read the scene data, ensure null termination
 1950|  4.02k|    static_assert(std::numeric_limits<uint32_t>::max() <= std::numeric_limits<size_t>::max(), "size_t must be at least 32bits");
 1951|  4.02k|    mSceneLength = chunk.chunkLength; // Can't be larger than 4GB (max. uint32_t)
 1952|  4.02k|    sceneData.resize(mSceneLength + 1);
 1953|  4.02k|    sceneData[mSceneLength] = '\0';
 1954|       |
 1955|  4.02k|    if (stream.Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
  ------------------
  |  Branch (1955:9): [True: 50, False: 3.97k]
  ------------------
 1956|     50|        throw DeadlyImportError("GLTF: Could not read the file contents");
 1957|     50|    }
 1958|       |
 1959|  3.97k|    uint32_t padding = ((chunk.chunkLength + 3) & ~3) - chunk.chunkLength;
 1960|  3.97k|    if (padding > 0) {
  ------------------
  |  Branch (1960:9): [True: 68, False: 3.90k]
  ------------------
 1961|     68|        stream.Seek(padding, aiOrigin_CUR);
 1962|     68|    }
 1963|       |
 1964|  3.97k|    AI_SWAP4(header.length);
 1965|  3.97k|    mBodyOffset = 12 + 8 + chunk.chunkLength + padding + 8;
 1966|  3.97k|    if (header.length >= mBodyOffset) {
  ------------------
  |  Branch (1966:9): [True: 3.91k, False: 64]
  ------------------
 1967|  3.91k|        if (stream.Read(&chunk, sizeof(chunk), 1) != 1) {
  ------------------
  |  Branch (1967:13): [True: 32, False: 3.88k]
  ------------------
 1968|     32|            throw DeadlyImportError("GLTF: Unable to read BIN chunk");
 1969|     32|        }
 1970|       |
 1971|  3.88k|        AI_SWAP4(chunk.chunkLength);
 1972|  3.88k|        AI_SWAP4(chunk.chunkType);
 1973|       |
 1974|  3.88k|        if (chunk.chunkType != ChunkType_BIN) {
  ------------------
  |  Branch (1974:13): [True: 110, False: 3.77k]
  ------------------
 1975|    110|            throw DeadlyImportError("GLTF: BIN chunk missing");
 1976|    110|        }
 1977|       |
 1978|  3.77k|        mBodyLength = chunk.chunkLength;
 1979|  3.77k|    } else {
 1980|     64|        mBodyOffset = mBodyLength = 0;
 1981|     64|    }
 1982|  3.97k|}
_ZN5glTF25Asset12ReadDocumentERN6Assimp8IOStreamEbRNSt3__16vectorIcNS4_9allocatorIcEEEE:
 1984|  6.32k|inline rapidjson::Document Asset::ReadDocument(IOStream &stream, bool isBinary, std::vector<char> &sceneData) {
 1985|  6.32k|    ASSIMP_LOG_DEBUG("Loading GLTF2 asset");
 1986|       |
 1987|       |    // is binary? then read the header
 1988|  6.32k|    if (isBinary) {
  ------------------
  |  Branch (1988:9): [True: 4.22k, False: 2.10k]
  ------------------
 1989|  4.22k|        SetAsBinary(); // also creates the body buffer
 1990|  4.22k|        ReadBinaryHeader(stream, sceneData);
 1991|  4.22k|    } else {
 1992|  2.10k|        mSceneLength = stream.FileSize();
 1993|  2.10k|        mBodyLength = 0;
 1994|       |
 1995|       |        // Binary format only supports up to 4GB of JSON, use that as a maximum
 1996|  2.10k|        if (mSceneLength >= std::numeric_limits<uint32_t>::max()) {
  ------------------
  |  Branch (1996:13): [True: 0, False: 2.10k]
  ------------------
 1997|      0|            throw DeadlyImportError("GLTF: JSON size greater than 4GB");
 1998|      0|        }
 1999|       |
 2000|       |        // read the scene data, ensure null termination
 2001|  2.10k|        sceneData.resize(mSceneLength + 1);
 2002|  2.10k|        sceneData[mSceneLength] = '\0';
 2003|       |
 2004|  2.10k|        if (stream.Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
  ------------------
  |  Branch (2004:13): [True: 0, False: 2.10k]
  ------------------
 2005|      0|            throw DeadlyImportError("GLTF: Could not read the file contents");
 2006|      0|        }
 2007|  2.10k|    }
 2008|       |
 2009|       |    // Smallest legal JSON file is "{}" Smallest loadable glTF file is larger than that but catch it later
 2010|  6.32k|    if (mSceneLength < 2) {
  ------------------
  |  Branch (2010:9): [True: 0, False: 6.32k]
  ------------------
 2011|      0|        throw DeadlyImportError("GLTF: No JSON file contents");
 2012|      0|    }
 2013|       |
 2014|       |    // parse the JSON document
 2015|  6.32k|    ASSIMP_LOG_DEBUG("Parsing GLTF2 JSON");
 2016|  6.32k|    Document doc;
 2017|  6.32k|    doc.ParseInsitu(&sceneData[0]);
 2018|       |
 2019|  6.32k|    if (doc.HasParseError()) {
  ------------------
  |  Branch (2019:9): [True: 1.31k, False: 5.00k]
  ------------------
 2020|  1.31k|        char buffer[32];
 2021|  1.31k|        ai_snprintf(buffer, 32, "%d", static_cast<int>(doc.GetErrorOffset()));
 2022|  1.31k|        throw DeadlyImportError("GLTF: JSON parse error, offset ", buffer, ": ", GetParseError_En(doc.GetParseError()));
 2023|  1.31k|    }
 2024|       |
 2025|  5.00k|    if (!doc.IsObject()) {
  ------------------
  |  Branch (2025:9): [True: 58, False: 4.95k]
  ------------------
 2026|     58|        throw DeadlyImportError("GLTF: JSON document root must be a JSON object");
 2027|     58|    }
 2028|       |
 2029|  4.95k|    return doc;
 2030|  5.00k|}
_ZN5glTF25Asset4LoadERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEb:
 2033|  2.17k|{
 2034|  2.17k|    mCurrentAssetDir.clear();
 2035|  2.17k|    if (0 != strncmp(pFile.c_str(), AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH)) {
  ------------------
  |  Branch (2035:9): [True: 0, False: 2.17k]
  ------------------
 2036|      0|        mCurrentAssetDir = glTFCommon::getCurrentAssetDir(pFile);
 2037|      0|    }
 2038|       |
 2039|  2.17k|    shared_ptr<IOStream> stream(OpenFile(pFile.c_str(), "rb", true));
 2040|  2.17k|    if (!stream) {
  ------------------
  |  Branch (2040:9): [True: 0, False: 2.17k]
  ------------------
 2041|      0|        throw DeadlyImportError("GLTF: Could not open file for reading");
 2042|      0|    }
 2043|       |
 2044|  2.17k|    std::vector<char> sceneData;
 2045|  2.17k|    rapidjson::Document doc = ReadDocument(*stream, isBinary, sceneData);
 2046|       |
 2047|       |    // If a schemaDocumentProvider is available, see if the glTF schema is present.
 2048|       |    // If so, use it to validate the document.
 2049|  2.17k|    if (mSchemaDocumentProvider) {
  ------------------
  |  Branch (2049:9): [True: 0, False: 2.17k]
  ------------------
 2050|      0|        if (const rapidjson::SchemaDocument *gltfSchema = mSchemaDocumentProvider->GetRemoteDocument("glTF.schema.json", 16)) {
  ------------------
  |  Branch (2050:46): [True: 0, False: 0]
  ------------------
 2051|       |            // The schemas are found here: https://github.com/KhronosGroup/glTF/tree/main/specification/2.0/schema
 2052|      0|            rapidjson::SchemaValidator validator(*gltfSchema);
 2053|      0|            if (!doc.Accept(validator)) {
  ------------------
  |  Branch (2053:17): [True: 0, False: 0]
  ------------------
 2054|      0|                rapidjson::StringBuffer pathBuffer;
 2055|      0|                validator.GetInvalidSchemaPointer().StringifyUriFragment(pathBuffer);
 2056|      0|                rapidjson::StringBuffer argumentBuffer;
 2057|      0|                validator.GetInvalidDocumentPointer().StringifyUriFragment(argumentBuffer);
 2058|      0|                throw DeadlyImportError("GLTF: The JSON document did not satisfy the glTF2 schema. Schema keyword: ", validator.GetInvalidSchemaKeyword(), ", document path: ", pathBuffer.GetString(), ", argument: ", argumentBuffer.GetString());
 2059|      0|            }
 2060|      0|        }
 2061|      0|    }
 2062|       |
 2063|       |    // Fill the buffer instance for the current file embedded contents
 2064|  2.17k|    if (mBodyLength > 0) {
  ------------------
  |  Branch (2064:9): [True: 1.87k, False: 298]
  ------------------
 2065|  1.87k|        if (!mBodyBuffer->LoadFromStream(*stream, mBodyLength, mBodyOffset)) {
  ------------------
  |  Branch (2065:13): [True: 15, False: 1.85k]
  ------------------
 2066|     15|            throw DeadlyImportError("GLTF: Unable to read gltf file");
 2067|     15|        }
 2068|  1.87k|    }
 2069|       |
 2070|       |    // Load the metadata
 2071|  2.15k|    asset.Read(doc);
 2072|  2.15k|    ReadExtensionsUsed(doc);
 2073|  2.15k|    ReadExtensionsRequired(doc);
 2074|       |
 2075|  2.15k|#ifndef ASSIMP_ENABLE_DRACO
 2076|       |    // Is Draco required?
 2077|  2.15k|    if (extensionsRequired.KHR_draco_mesh_compression) {
  ------------------
  |  Branch (2077:9): [True: 0, False: 2.15k]
  ------------------
 2078|      0|        throw DeadlyImportError("GLTF: Draco mesh compression not supported.");
 2079|      0|    }
 2080|  2.15k|#endif
 2081|       |
 2082|       |    // Prepare the dictionaries
 2083|  31.6k|    for (size_t i = 0; i < mDicts.size(); ++i) {
  ------------------
  |  Branch (2083:24): [True: 29.4k, False: 2.15k]
  ------------------
 2084|  29.4k|        mDicts[i]->AttachToDocument(doc);
 2085|  29.4k|    }
 2086|       |
 2087|       |    // Read the "extensions" property, then add it to each scene's metadata.
 2088|  2.15k|    CustomExtension customExtensions;
 2089|  2.15k|    if (Value *extensionsObject = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (2089:16): [True: 0, False: 2.15k]
  ------------------
 2090|      0|        customExtensions = glTF2::ReadExtensions("extensions", *extensionsObject);
 2091|      0|    }
 2092|       |
 2093|       |    // Read the "scene" property, which specifies which scene to load
 2094|       |    // and recursively load everything referenced by it
 2095|  2.15k|    unsigned int sceneIndex = 0;
 2096|  2.15k|    Value *curScene = FindUInt(doc, "scene");
 2097|  2.15k|    if (nullptr != curScene) {
  ------------------
  |  Branch (2097:9): [True: 1.95k, False: 207]
  ------------------
 2098|  1.95k|        sceneIndex = curScene->GetUint();
 2099|  1.95k|    }
 2100|       |
 2101|  2.15k|    if (Value *scenesArray = FindArray(doc, "scenes")) {
  ------------------
  |  Branch (2101:16): [True: 2.00k, False: 149]
  ------------------
 2102|  2.00k|        if (sceneIndex < scenesArray->Size()) {
  ------------------
  |  Branch (2102:13): [True: 1.98k, False: 22]
  ------------------
 2103|  1.98k|            this->scene = scenes.Retrieve(sceneIndex);
 2104|       |
 2105|  1.98k|            this->scene->customExtensions = customExtensions;
 2106|  1.98k|        }
 2107|  2.00k|    }
 2108|       |
 2109|  2.15k|    if (Value *skinsArray = FindArray(doc, "skins")) {
  ------------------
  |  Branch (2109:16): [True: 376, False: 1.78k]
  ------------------
 2110|    765|        for (unsigned int i = 0; i < skinsArray->Size(); ++i) {
  ------------------
  |  Branch (2110:34): [True: 389, False: 376]
  ------------------
 2111|    389|            skins.Retrieve(i);
 2112|    389|        }
 2113|    376|    }
 2114|       |
 2115|  2.15k|    if (Value *animsArray = FindArray(doc, "animations")) {
  ------------------
  |  Branch (2115:16): [True: 0, False: 2.15k]
  ------------------
 2116|      0|        for (unsigned int i = 0; i < animsArray->Size(); ++i) {
  ------------------
  |  Branch (2116:34): [True: 0, False: 0]
  ------------------
 2117|      0|            animations.Retrieve(i);
 2118|      0|        }
 2119|      0|    }
 2120|       |
 2121|       |    // Clean up
 2122|  27.4k|    for (size_t i = 0; i < mDicts.size(); ++i) {
  ------------------
  |  Branch (2122:24): [True: 25.2k, False: 2.15k]
  ------------------
 2123|  25.2k|        mDicts[i]->DetachFromDocument();
 2124|  25.2k|    }
 2125|  2.15k|}
_ZN5glTF25Asset7CanReadERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEb:
 2127|  4.15k|inline bool Asset::CanRead(const std::string &pFile, bool isBinary) {
 2128|  4.15k|    try {
 2129|  4.15k|        shared_ptr<IOStream> stream(OpenFile(pFile.c_str(), "rb", true));
 2130|  4.15k|        if (!stream) {
  ------------------
  |  Branch (2130:13): [True: 0, False: 4.15k]
  ------------------
 2131|      0|            return false;
 2132|      0|        }
 2133|  4.15k|        std::vector<char> sceneData;
 2134|  4.15k|        rapidjson::Document doc = ReadDocument(*stream, isBinary, sceneData);
 2135|  4.15k|        asset.Read(doc);
 2136|  4.15k|    } catch (...) {
 2137|  1.98k|        return false;
 2138|  1.98k|    }
 2139|  2.17k|    return true;
 2140|  4.15k|}
_ZN5glTF25Asset11SetAsBinaryEv:
 2142|  4.22k|inline void Asset::SetAsBinary() {
 2143|  4.22k|    if (!mBodyBuffer) {
  ------------------
  |  Branch (2143:9): [True: 4.22k, False: 0]
  ------------------
 2144|  4.22k|        mBodyBuffer = buffers.Create("binary_glTF");
 2145|  4.22k|        mBodyBuffer->MarkAsSpecial();
 2146|  4.22k|    }
 2147|  4.22k|}
_ZN5glTF25Asset22ReadExtensionsRequiredERN9rapidjson15GenericDocumentINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEES6_EE:
 2154|  2.11k|inline void Asset::ReadExtensionsRequired(Document &doc) {
 2155|  2.11k|    Value *extsRequired = FindArray(doc, "extensionsRequired");
 2156|  2.11k|    if (nullptr == extsRequired) {
  ------------------
  |  Branch (2156:9): [True: 2.11k, False: 0]
  ------------------
 2157|  2.11k|        return;
 2158|  2.11k|    }
 2159|       |
 2160|      0|    std::gltf_unordered_map<std::string, bool> exts;
 2161|      0|    for (unsigned int i = 0; i < extsRequired->Size(); ++i) {
  ------------------
  |  Branch (2161:30): [True: 0, False: 0]
  ------------------
 2162|      0|        if ((*extsRequired)[i].IsString()) {
  ------------------
  |  Branch (2162:13): [True: 0, False: 0]
  ------------------
 2163|      0|            exts[(*extsRequired)[i].GetString()] = true;
 2164|      0|        }
 2165|      0|    }
 2166|       |
 2167|      0|    CHECK_REQUIRED_EXT(KHR_draco_mesh_compression);
  ------------------
  |  | 2152|      0|    if (exts.find(#EXT) != exts.end()) extensionsRequired.EXT = true;
  |  |  ------------------
  |  |  |  Branch (2152:9): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2168|      0|    CHECK_REQUIRED_EXT(KHR_texture_basisu);
  ------------------
  |  | 2152|      0|    if (exts.find(#EXT) != exts.end()) extensionsRequired.EXT = true;
  |  |  ------------------
  |  |  |  Branch (2152:9): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2169|      0|    CHECK_REQUIRED_EXT(EXT_texture_webp);
  ------------------
  |  | 2152|      0|    if (exts.find(#EXT) != exts.end()) extensionsRequired.EXT = true;
  |  |  ------------------
  |  |  |  Branch (2152:9): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 2170|       |
 2171|      0|#undef CHECK_REQUIRED_EXT
 2172|      0|}
_ZN5glTF25Asset18ReadExtensionsUsedERN9rapidjson15GenericDocumentINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEES6_EE:
 2174|  2.11k|inline void Asset::ReadExtensionsUsed(Document &doc) {
 2175|  2.11k|    Value *extsUsed = FindArray(doc, "extensionsUsed");
 2176|  2.11k|    if (!extsUsed) return;
  ------------------
  |  Branch (2176:9): [True: 1.67k, False: 436]
  ------------------
 2177|       |
 2178|    436|    std::gltf_unordered_map<std::string, bool> exts;
 2179|       |
 2180|  1.31k|    for (unsigned int i = 0; i < extsUsed->Size(); ++i) {
  ------------------
  |  Branch (2180:30): [True: 876, False: 436]
  ------------------
 2181|    876|        if ((*extsUsed)[i].IsString()) {
  ------------------
  |  Branch (2181:13): [True: 875, False: 1]
  ------------------
 2182|    875|            exts[(*extsUsed)[i].GetString()] = true;
 2183|    875|        }
 2184|    876|    }
 2185|       |
 2186|    436|    CHECK_EXT(KHR_materials_pbrSpecularGlossiness);
  ------------------
  |  |  237|    436|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 436]
  |  |  ------------------
  ------------------
 2187|    436|    CHECK_EXT(KHR_materials_specular);
  ------------------
  |  |  237|    436|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 436]
  |  |  ------------------
  ------------------
 2188|    436|    CHECK_EXT(KHR_materials_unlit);
  ------------------
  |  |  237|    436|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 436]
  |  |  ------------------
  ------------------
 2189|    436|    CHECK_EXT(KHR_lights_punctual);
  ------------------
  |  |  237|    436|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 436]
  |  |  ------------------
  ------------------
 2190|    436|    CHECK_EXT(KHR_texture_transform);
  ------------------
  |  |  237|    436|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 436]
  |  |  ------------------
  ------------------
 2191|    436|    CHECK_EXT(KHR_materials_sheen);
  ------------------
  |  |  237|    436|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 436]
  |  |  ------------------
  ------------------
 2192|    436|    CHECK_EXT(KHR_materials_clearcoat);
  ------------------
  |  |  237|    436|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 436]
  |  |  ------------------
  ------------------
 2193|    436|    CHECK_EXT(KHR_materials_transmission);
  ------------------
  |  |  237|    436|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 436]
  |  |  ------------------
  ------------------
 2194|    436|    CHECK_EXT(KHR_materials_volume);
  ------------------
  |  |  237|    436|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 362, False: 74]
  |  |  ------------------
  ------------------
 2195|    436|    CHECK_EXT(KHR_materials_ior);
  ------------------
  |  |  237|    436|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 436]
  |  |  ------------------
  ------------------
 2196|    436|    CHECK_EXT(KHR_materials_emissive_strength);
  ------------------
  |  |  237|    436|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 436]
  |  |  ------------------
  ------------------
 2197|    436|    CHECK_EXT(KHR_materials_anisotropy);
  ------------------
  |  |  237|    436|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 436]
  |  |  ------------------
  ------------------
 2198|    436|    CHECK_EXT(KHR_draco_mesh_compression);
  ------------------
  |  |  237|    436|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 436]
  |  |  ------------------
  ------------------
 2199|    436|    CHECK_EXT(KHR_texture_basisu);
  ------------------
  |  |  237|    436|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 436]
  |  |  ------------------
  ------------------
 2200|    436|    CHECK_EXT(EXT_texture_webp);
  ------------------
  |  |  237|    436|    if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
  |  |  ------------------
  |  |  |  Branch (237:9): [True: 0, False: 436]
  |  |  ------------------
  ------------------
 2201|       |
 2202|    436|#undef CHECK_EXT
 2203|    436|}
_ZN5glTF25Asset8OpenFileERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEPKcb:
 2205|  6.32k|inline IOStream *Asset::OpenFile(const std::string &path, const char *mode, bool /*absolute*/) {
 2206|  6.32k|#ifdef ASSIMP_API
 2207|  6.32k|    return mIOSystem->Open(path, mode);
 2208|       |#else
 2209|       |    if (path.size() < 2) return nullptr;
 2210|       |    if (!absolute && path[1] != ':' && path[0] != '/') { // relative?
 2211|       |        path = mCurrentAssetDir + path;
 2212|       |    }
 2213|       |    FILE *f = fopen(path.c_str(), mode);
 2214|       |    return f ? new IOStream(f) : nullptr;
 2215|       |#endif
 2216|  6.32k|}
_ZN5glTF28Accessor7Indexer8GetValueIjEET_i:
 1117|  25.0k|T Accessor::Indexer::GetValue(int i) {
 1118|  25.0k|    ai_assert(data);
 1119|  25.0k|    if (i * stride >= accessor.GetMaxByteSize()) {
  ------------------
  |  Branch (1119:9): [True: 1, False: 25.0k]
  ------------------
 1120|      1|        throw DeadlyImportError("GLTF: Invalid index ", i, ", count out of range for buffer with stride ", stride, " and size ", accessor.GetMaxByteSize(), ".");
 1121|      1|    }
 1122|       |    // Ensure that the memcpy doesn't overwrite the local.
 1123|  25.0k|    const size_t sizeToCopy = std::min(elemSize, sizeof(T));
 1124|  25.0k|    T value = T();
 1125|       |    // Assume platform endianness matches GLTF binary data (which is little-endian).
 1126|  25.0k|    memcpy(&value, data + i * stride, sizeToCopy);
 1127|  25.0k|    return value;
 1128|  25.0k|}
_ZN5glTF28LazyDictINS_8AccessorEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.11k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.11k|    Value *container = nullptr;
  407|  2.11k|    const char *context = nullptr;
  408|       |
  409|  2.11k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.11k]
  ------------------
  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.11k|    } else {
  415|  2.11k|        container = &doc;
  416|  2.11k|        context = "the document";
  417|  2.11k|    }
  418|       |
  419|  2.11k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.11k, False: 0]
  ------------------
  420|  2.11k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.11k|    }
  422|  2.11k|}
_ZN5glTF28LazyDictINS_8AccessorEE18DetachFromDocumentEv:
  425|  1.80k|inline void LazyDict<T>::DetachFromDocument() {
  426|  1.80k|    mDict = nullptr;
  427|  1.80k|}
_ZN5glTF28LazyDictINS_9AnimationEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.10k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.10k|    Value *container = nullptr;
  407|  2.10k|    const char *context = nullptr;
  408|       |
  409|  2.10k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.10k]
  ------------------
  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.10k|    } else {
  415|  2.10k|        container = &doc;
  416|  2.10k|        context = "the document";
  417|  2.10k|    }
  418|       |
  419|  2.10k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.10k, False: 0]
  ------------------
  420|  2.10k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.10k|    }
  422|  2.10k|}
_ZN5glTF28LazyDictINS_9AnimationEE18DetachFromDocumentEv:
  425|  1.80k|inline void LazyDict<T>::DetachFromDocument() {
  426|  1.80k|    mDict = nullptr;
  427|  1.80k|}
_ZN5glTF28LazyDictINS_6BufferEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.10k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.10k|    Value *container = nullptr;
  407|  2.10k|    const char *context = nullptr;
  408|       |
  409|  2.10k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.10k]
  ------------------
  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.10k|    } else {
  415|  2.10k|        container = &doc;
  416|  2.10k|        context = "the document";
  417|  2.10k|    }
  418|       |
  419|  2.10k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.10k, False: 0]
  ------------------
  420|  2.10k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.10k|    }
  422|  2.10k|}
_ZN5glTF28LazyDictINS_6BufferEE18DetachFromDocumentEv:
  425|  1.80k|inline void LazyDict<T>::DetachFromDocument() {
  426|  1.80k|    mDict = nullptr;
  427|  1.80k|}
_ZN5glTF28LazyDictINS_10BufferViewEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.10k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.10k|    Value *container = nullptr;
  407|  2.10k|    const char *context = nullptr;
  408|       |
  409|  2.10k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.10k]
  ------------------
  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.10k|    } else {
  415|  2.10k|        container = &doc;
  416|  2.10k|        context = "the document";
  417|  2.10k|    }
  418|       |
  419|  2.10k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.10k, False: 0]
  ------------------
  420|  2.10k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.10k|    }
  422|  2.10k|}
_ZN5glTF28LazyDictINS_10BufferViewEE18DetachFromDocumentEv:
  425|  1.80k|inline void LazyDict<T>::DetachFromDocument() {
  426|  1.80k|    mDict = nullptr;
  427|  1.80k|}
_ZN5glTF28LazyDictINS_6CameraEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.10k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.10k|    Value *container = nullptr;
  407|  2.10k|    const char *context = nullptr;
  408|       |
  409|  2.10k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.10k]
  ------------------
  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.10k|    } else {
  415|  2.10k|        container = &doc;
  416|  2.10k|        context = "the document";
  417|  2.10k|    }
  418|       |
  419|  2.10k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.10k, False: 0]
  ------------------
  420|  2.10k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.10k|    }
  422|  2.10k|}
_ZN5glTF28LazyDictINS_6CameraEE18DetachFromDocumentEv:
  425|  1.80k|inline void LazyDict<T>::DetachFromDocument() {
  426|  1.80k|    mDict = nullptr;
  427|  1.80k|}
_ZN5glTF28LazyDictINS_5LightEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.10k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.10k|    Value *container = nullptr;
  407|  2.10k|    const char *context = nullptr;
  408|       |
  409|  2.10k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 2.10k, False: 0]
  ------------------
  410|  2.10k|        if (Value *exts = FindObject(doc, "extensions")) {
  ------------------
  |  Branch (410:20): [True: 0, False: 2.10k]
  ------------------
  411|      0|            container = FindObjectInContext(*exts, mExtId, "extensions");
  412|      0|            context = mExtId;
  413|      0|        }
  414|  2.10k|    } else {
  415|      0|        container = &doc;
  416|      0|        context = "the document";
  417|      0|    }
  418|       |
  419|  2.10k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 0, False: 2.10k]
  ------------------
  420|      0|        mDict = FindArrayInContext(*container, mDictId, context);
  421|      0|    }
  422|  2.10k|}
_ZN5glTF28LazyDictINS_5LightEE18DetachFromDocumentEv:
  425|  1.80k|inline void LazyDict<T>::DetachFromDocument() {
  426|  1.80k|    mDict = nullptr;
  427|  1.80k|}
_ZN5glTF28LazyDictINS_5ImageEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.10k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.10k|    Value *container = nullptr;
  407|  2.10k|    const char *context = nullptr;
  408|       |
  409|  2.10k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.10k]
  ------------------
  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.10k|    } else {
  415|  2.10k|        container = &doc;
  416|  2.10k|        context = "the document";
  417|  2.10k|    }
  418|       |
  419|  2.10k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.10k, False: 0]
  ------------------
  420|  2.10k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.10k|    }
  422|  2.10k|}
_ZN5glTF28LazyDictINS_5ImageEE18DetachFromDocumentEv:
  425|  1.80k|inline void LazyDict<T>::DetachFromDocument() {
  426|  1.80k|    mDict = nullptr;
  427|  1.80k|}
_ZN5glTF28LazyDictINS_8MaterialEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.10k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.10k|    Value *container = nullptr;
  407|  2.10k|    const char *context = nullptr;
  408|       |
  409|  2.10k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.10k]
  ------------------
  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.10k|    } else {
  415|  2.10k|        container = &doc;
  416|  2.10k|        context = "the document";
  417|  2.10k|    }
  418|       |
  419|  2.10k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.10k, False: 0]
  ------------------
  420|  2.10k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.10k|    }
  422|  2.10k|}
_ZN5glTF28LazyDictINS_8MaterialEE18DetachFromDocumentEv:
  425|  1.80k|inline void LazyDict<T>::DetachFromDocument() {
  426|  1.80k|    mDict = nullptr;
  427|  1.80k|}
_ZN5glTF28LazyDictINS_4MeshEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.10k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.10k|    Value *container = nullptr;
  407|  2.10k|    const char *context = nullptr;
  408|       |
  409|  2.10k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.10k]
  ------------------
  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.10k|    } else {
  415|  2.10k|        container = &doc;
  416|  2.10k|        context = "the document";
  417|  2.10k|    }
  418|       |
  419|  2.10k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.10k, False: 0]
  ------------------
  420|  2.10k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.10k|    }
  422|  2.10k|}
_ZN5glTF28LazyDictINS_4MeshEE18DetachFromDocumentEv:
  425|  1.80k|inline void LazyDict<T>::DetachFromDocument() {
  426|  1.80k|    mDict = nullptr;
  427|  1.80k|}
_ZN5glTF28LazyDictINS_4NodeEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.10k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.10k|    Value *container = nullptr;
  407|  2.10k|    const char *context = nullptr;
  408|       |
  409|  2.10k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.10k]
  ------------------
  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.10k|    } else {
  415|  2.10k|        container = &doc;
  416|  2.10k|        context = "the document";
  417|  2.10k|    }
  418|       |
  419|  2.10k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.10k, False: 0]
  ------------------
  420|  2.10k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.10k|    }
  422|  2.10k|}
_ZN5glTF28LazyDictINS_4NodeEE18DetachFromDocumentEv:
  425|  1.80k|inline void LazyDict<T>::DetachFromDocument() {
  426|  1.80k|    mDict = nullptr;
  427|  1.80k|}
_ZN5glTF28LazyDictINS_7SamplerEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.10k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.10k|    Value *container = nullptr;
  407|  2.10k|    const char *context = nullptr;
  408|       |
  409|  2.10k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.10k]
  ------------------
  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.10k|    } else {
  415|  2.10k|        container = &doc;
  416|  2.10k|        context = "the document";
  417|  2.10k|    }
  418|       |
  419|  2.10k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.10k, False: 0]
  ------------------
  420|  2.10k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.10k|    }
  422|  2.10k|}
_ZN5glTF28LazyDictINS_7SamplerEE18DetachFromDocumentEv:
  425|  1.80k|inline void LazyDict<T>::DetachFromDocument() {
  426|  1.80k|    mDict = nullptr;
  427|  1.80k|}
_ZN5glTF28LazyDictINS_5SceneEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.10k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.10k|    Value *container = nullptr;
  407|  2.10k|    const char *context = nullptr;
  408|       |
  409|  2.10k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.10k]
  ------------------
  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.10k|    } else {
  415|  2.10k|        container = &doc;
  416|  2.10k|        context = "the document";
  417|  2.10k|    }
  418|       |
  419|  2.10k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.10k, False: 0]
  ------------------
  420|  2.10k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.10k|    }
  422|  2.10k|}
_ZN5glTF28LazyDictINS_5SceneEE18DetachFromDocumentEv:
  425|  1.80k|inline void LazyDict<T>::DetachFromDocument() {
  426|  1.80k|    mDict = nullptr;
  427|  1.80k|}
_ZN5glTF28LazyDictINS_4SkinEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.09k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.09k|    Value *container = nullptr;
  407|  2.09k|    const char *context = nullptr;
  408|       |
  409|  2.09k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.09k]
  ------------------
  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.09k|    } else {
  415|  2.09k|        container = &doc;
  416|  2.09k|        context = "the document";
  417|  2.09k|    }
  418|       |
  419|  2.09k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.09k, False: 0]
  ------------------
  420|  2.09k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.09k|    }
  422|  2.09k|}
_ZN5glTF28LazyDictINS_4SkinEE18DetachFromDocumentEv:
  425|  1.80k|inline void LazyDict<T>::DetachFromDocument() {
  426|  1.80k|    mDict = nullptr;
  427|  1.80k|}
_ZN5glTF28LazyDictINS_7TextureEE16AttachToDocumentERN9rapidjson15GenericDocumentINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEES8_EE:
  405|  2.09k|inline void LazyDict<T>::AttachToDocument(Document &doc) {
  406|  2.09k|    Value *container = nullptr;
  407|  2.09k|    const char *context = nullptr;
  408|       |
  409|  2.09k|    if (mExtId) {
  ------------------
  |  Branch (409:9): [True: 0, False: 2.09k]
  ------------------
  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.09k|    } else {
  415|  2.09k|        container = &doc;
  416|  2.09k|        context = "the document";
  417|  2.09k|    }
  418|       |
  419|  2.09k|    if (container) {
  ------------------
  |  Branch (419:9): [True: 2.09k, False: 0]
  ------------------
  420|  2.09k|        mDict = FindArrayInContext(*container, mDictId, context);
  421|  2.09k|    }
  422|  2.09k|}
_ZN5glTF28LazyDictINS_7TextureEE18DetachFromDocumentEv:
  425|  1.80k|inline void LazyDict<T>::DetachFromDocument() {
  426|  1.80k|    mDict = nullptr;
  427|  1.80k|}
_ZN5glTF28LazyDictINS_6BufferEE8RetrieveEj:
  473|  6.68k|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|  6.68k|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|  6.68k|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 6.67k, False: 9]
  ------------------
  476|  6.67k|        return Ref<T>(mObjs, it->second);
  477|  6.67k|    }
  478|       |
  479|       |    // read it from the JSON object
  480|      9|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 1, False: 8]
  ------------------
  481|      1|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      1|    }
  483|       |
  484|      8|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 8]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|      8|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 8, False: 0]
  ------------------
  489|      8|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|      8|    }
  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.22k|Ref<T> LazyDict<T>::Add(T *obj) {
  537|  4.22k|    unsigned int idx = unsigned(mObjs.size());
  538|  4.22k|    mObjs.push_back(obj);
  539|  4.22k|    mObjsByOIndex[obj->oIndex] = idx;
  540|  4.22k|    mObjsById[obj->id] = idx;
  541|  4.22k|    return Ref<T>(mObjs, idx);
  542|  4.22k|}
_ZN5glTF28LazyDictINS_10BufferViewEE8RetrieveEj:
  473|  7.03k|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|  7.03k|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|  7.03k|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 326, False: 6.71k]
  ------------------
  476|    326|        return Ref<T>(mObjs, it->second);
  477|    326|    }
  478|       |
  479|       |    // read it from the JSON object
  480|  6.71k|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 4, False: 6.70k]
  ------------------
  481|      4|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      4|    }
  483|       |
  484|  6.70k|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 6.70k]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|  6.70k|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 11, False: 6.69k]
  ------------------
  489|     11|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|     11|    }
  491|       |
  492|  6.69k|    Value &obj = (*mDict)[i];
  493|       |
  494|  6.69k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 0, False: 6.69k]
  ------------------
  495|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      0|    }
  497|       |
  498|  6.69k|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 0, False: 6.69k]
  ------------------
  499|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|      0|    }
  501|  6.69k|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|  6.69k|    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.69k|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|  6.69k|    inst->oIndex = i;
  508|  6.69k|    ReadMember(obj, "name", inst->name);
  509|  6.69k|    inst->Read(obj, mAsset);
  510|  6.69k|    inst->ReadExtensions(obj);
  511|  6.69k|    inst->ReadExtras(obj);
  512|       |
  513|  6.69k|    Ref<T> result = Add(inst.release());
  514|  6.69k|    mRecursiveReferenceCheck.erase(i);
  515|  6.69k|    return result;
  516|  6.69k|}
_ZN5glTF28LazyDictINS_10BufferViewEE3AddEPS1_:
  536|  6.65k|Ref<T> LazyDict<T>::Add(T *obj) {
  537|  6.65k|    unsigned int idx = unsigned(mObjs.size());
  538|  6.65k|    mObjs.push_back(obj);
  539|  6.65k|    mObjsByOIndex[obj->oIndex] = idx;
  540|  6.65k|    mObjsById[obj->id] = idx;
  541|  6.65k|    return Ref<T>(mObjs, idx);
  542|  6.65k|}
_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|     57|Ref<T> LazyDict<T>::Add(T *obj) {
  537|     57|    unsigned int idx = unsigned(mObjs.size());
  538|     57|    mObjs.push_back(obj);
  539|     57|    mObjsByOIndex[obj->oIndex] = idx;
  540|     57|    mObjsById[obj->id] = idx;
  541|     57|    return Ref<T>(mObjs, idx);
  542|     57|}
_ZN5glTF28LazyDictINS_7SamplerEE8RetrieveEj:
  473|     60|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|     60|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|     60|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 0, False: 60]
  ------------------
  476|      0|        return Ref<T>(mObjs, it->second);
  477|      0|    }
  478|       |
  479|       |    // read it from the JSON object
  480|     60|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 1, False: 59]
  ------------------
  481|      1|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      1|    }
  483|       |
  484|     59|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 59]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|     59|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 1, False: 58]
  ------------------
  489|      1|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|      1|    }
  491|       |
  492|     58|    Value &obj = (*mDict)[i];
  493|       |
  494|     58|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 0, False: 58]
  ------------------
  495|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      0|    }
  497|       |
  498|     58|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 0, False: 58]
  ------------------
  499|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|      0|    }
  501|     58|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|     58|    auto inst = std::unique_ptr<T>(new T());
  505|       |    // Try to make this human readable so it can be used in error messages.
  506|     58|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|     58|    inst->oIndex = i;
  508|     58|    ReadMember(obj, "name", inst->name);
  509|     58|    inst->Read(obj, mAsset);
  510|     58|    inst->ReadExtensions(obj);
  511|     58|    inst->ReadExtras(obj);
  512|       |
  513|     58|    Ref<T> result = Add(inst.release());
  514|     58|    mRecursiveReferenceCheck.erase(i);
  515|     58|    return result;
  516|     58|}
_ZN5glTF28LazyDictINS_7SamplerEE3AddEPS1_:
  536|     58|Ref<T> LazyDict<T>::Add(T *obj) {
  537|     58|    unsigned int idx = unsigned(mObjs.size());
  538|     58|    mObjs.push_back(obj);
  539|     58|    mObjsByOIndex[obj->oIndex] = idx;
  540|     58|    mObjsById[obj->id] = idx;
  541|     58|    return Ref<T>(mObjs, idx);
  542|     58|}
_ZN5glTF28LazyDictINS_7TextureEE8RetrieveEj:
  473|     74|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|     74|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|     74|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 0, False: 74]
  ------------------
  476|      0|        return Ref<T>(mObjs, it->second);
  477|      0|    }
  478|       |
  479|       |    // read it from the JSON object
  480|     74|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 1, False: 73]
  ------------------
  481|      1|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      1|    }
  483|       |
  484|     73|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 73]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|     73|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 2, False: 71]
  ------------------
  489|      2|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|      2|    }
  491|       |
  492|     71|    Value &obj = (*mDict)[i];
  493|       |
  494|     71|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 0, False: 71]
  ------------------
  495|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      0|    }
  497|       |
  498|     71|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 0, False: 71]
  ------------------
  499|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|      0|    }
  501|     71|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|     71|    auto inst = std::unique_ptr<T>(new T());
  505|       |    // Try to make this human readable so it can be used in error messages.
  506|     71|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|     71|    inst->oIndex = i;
  508|     71|    ReadMember(obj, "name", inst->name);
  509|     71|    inst->Read(obj, mAsset);
  510|     71|    inst->ReadExtensions(obj);
  511|     71|    inst->ReadExtras(obj);
  512|       |
  513|     71|    Ref<T> result = Add(inst.release());
  514|     71|    mRecursiveReferenceCheck.erase(i);
  515|     71|    return result;
  516|     71|}
_ZN5glTF28LazyDictINS_7TextureEE3AddEPS1_:
  536|     63|Ref<T> LazyDict<T>::Add(T *obj) {
  537|     63|    unsigned int idx = unsigned(mObjs.size());
  538|     63|    mObjs.push_back(obj);
  539|     63|    mObjsByOIndex[obj->oIndex] = idx;
  540|     63|    mObjsById[obj->id] = idx;
  541|     63|    return Ref<T>(mObjs, idx);
  542|     63|}
_ZN5glTF28LazyDictINS_8AccessorEE8RetrieveEj:
  473|  7.32k|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|  7.32k|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|  7.32k|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 196, False: 7.12k]
  ------------------
  476|    196|        return Ref<T>(mObjs, it->second);
  477|    196|    }
  478|       |
  479|       |    // read it from the JSON object
  480|  7.12k|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 3, False: 7.12k]
  ------------------
  481|      3|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      3|    }
  483|       |
  484|  7.12k|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 7.12k]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|  7.12k|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 12, False: 7.11k]
  ------------------
  489|     12|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|     12|    }
  491|       |
  492|  7.11k|    Value &obj = (*mDict)[i];
  493|       |
  494|  7.11k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 0, False: 7.11k]
  ------------------
  495|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      0|    }
  497|       |
  498|  7.11k|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 0, False: 7.11k]
  ------------------
  499|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|      0|    }
  501|  7.11k|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|  7.11k|    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.11k|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|  7.11k|    inst->oIndex = i;
  508|  7.11k|    ReadMember(obj, "name", inst->name);
  509|  7.11k|    inst->Read(obj, mAsset);
  510|  7.11k|    inst->ReadExtensions(obj);
  511|  7.11k|    inst->ReadExtras(obj);
  512|       |
  513|  7.11k|    Ref<T> result = Add(inst.release());
  514|  7.11k|    mRecursiveReferenceCheck.erase(i);
  515|  7.11k|    return result;
  516|  7.11k|}
_ZN5glTF28LazyDictINS_8AccessorEE3AddEPS1_:
  536|  6.98k|Ref<T> LazyDict<T>::Add(T *obj) {
  537|  6.98k|    unsigned int idx = unsigned(mObjs.size());
  538|  6.98k|    mObjs.push_back(obj);
  539|  6.98k|    mObjsByOIndex[obj->oIndex] = idx;
  540|  6.98k|    mObjsById[obj->id] = idx;
  541|  6.98k|    return Ref<T>(mObjs, idx);
  542|  6.98k|}
_ZN5glTF28LazyDictINS_8MaterialEE8RetrieveEj:
  473|  1.43k|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|  1.43k|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|  1.43k|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 0, False: 1.43k]
  ------------------
  476|      0|        return Ref<T>(mObjs, it->second);
  477|      0|    }
  478|       |
  479|       |    // read it from the JSON object
  480|  1.43k|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 3, False: 1.43k]
  ------------------
  481|      3|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      3|    }
  483|       |
  484|  1.43k|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 1.43k]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|  1.43k|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 4, False: 1.42k]
  ------------------
  489|      4|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|      4|    }
  491|       |
  492|  1.42k|    Value &obj = (*mDict)[i];
  493|       |
  494|  1.42k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 0, False: 1.42k]
  ------------------
  495|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      0|    }
  497|       |
  498|  1.42k|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 0, False: 1.42k]
  ------------------
  499|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|      0|    }
  501|  1.42k|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|  1.42k|    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.42k|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|  1.42k|    inst->oIndex = i;
  508|  1.42k|    ReadMember(obj, "name", inst->name);
  509|  1.42k|    inst->Read(obj, mAsset);
  510|  1.42k|    inst->ReadExtensions(obj);
  511|  1.42k|    inst->ReadExtras(obj);
  512|       |
  513|  1.42k|    Ref<T> result = Add(inst.release());
  514|  1.42k|    mRecursiveReferenceCheck.erase(i);
  515|  1.42k|    return result;
  516|  1.42k|}
_ZN5glTF28LazyDictINS_8MaterialEE3AddEPS1_:
  536|  1.41k|Ref<T> LazyDict<T>::Add(T *obj) {
  537|  1.41k|    unsigned int idx = unsigned(mObjs.size());
  538|  1.41k|    mObjs.push_back(obj);
  539|  1.41k|    mObjsByOIndex[obj->oIndex] = idx;
  540|  1.41k|    mObjsById[obj->id] = idx;
  541|  1.41k|    return Ref<T>(mObjs, idx);
  542|  1.41k|}
_ZN5glTF28LazyDictINS_4NodeEE8RetrieveEj:
  473|  14.8k|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|  14.8k|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|  14.8k|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 2.90k, False: 11.9k]
  ------------------
  476|  2.90k|        return Ref<T>(mObjs, it->second);
  477|  2.90k|    }
  478|       |
  479|       |    // read it from the JSON object
  480|  11.9k|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 10, False: 11.9k]
  ------------------
  481|     10|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|     10|    }
  483|       |
  484|  11.9k|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 11.9k]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|  11.9k|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 33, False: 11.8k]
  ------------------
  489|     33|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|     33|    }
  491|       |
  492|  11.8k|    Value &obj = (*mDict)[i];
  493|       |
  494|  11.8k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 1, False: 11.8k]
  ------------------
  495|      1|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      1|    }
  497|       |
  498|  11.8k|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 11, False: 11.8k]
  ------------------
  499|     11|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|     11|    }
  501|  11.8k|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|  11.8k|    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.8k|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|  11.8k|    inst->oIndex = i;
  508|  11.8k|    ReadMember(obj, "name", inst->name);
  509|  11.8k|    inst->Read(obj, mAsset);
  510|  11.8k|    inst->ReadExtensions(obj);
  511|  11.8k|    inst->ReadExtras(obj);
  512|       |
  513|  11.8k|    Ref<T> result = Add(inst.release());
  514|  11.8k|    mRecursiveReferenceCheck.erase(i);
  515|  11.8k|    return result;
  516|  11.8k|}
_ZN5glTF28LazyDictINS_4NodeEE3AddEPS1_:
  536|  11.3k|Ref<T> LazyDict<T>::Add(T *obj) {
  537|  11.3k|    unsigned int idx = unsigned(mObjs.size());
  538|  11.3k|    mObjs.push_back(obj);
  539|  11.3k|    mObjsByOIndex[obj->oIndex] = idx;
  540|  11.3k|    mObjsById[obj->id] = idx;
  541|  11.3k|    return Ref<T>(mObjs, idx);
  542|  11.3k|}
_ZN5glTF28LazyDictINS_4MeshEE8RetrieveEj:
  473|  1.80k|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|  1.80k|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|  1.80k|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 0, False: 1.80k]
  ------------------
  476|      0|        return Ref<T>(mObjs, it->second);
  477|      0|    }
  478|       |
  479|       |    // read it from the JSON object
  480|  1.80k|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 6, False: 1.79k]
  ------------------
  481|      6|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      6|    }
  483|       |
  484|  1.79k|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 1.79k]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|  1.79k|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 7, False: 1.79k]
  ------------------
  489|      7|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|      7|    }
  491|       |
  492|  1.79k|    Value &obj = (*mDict)[i];
  493|       |
  494|  1.79k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 1, False: 1.79k]
  ------------------
  495|      1|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      1|    }
  497|       |
  498|  1.79k|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 0, False: 1.79k]
  ------------------
  499|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|      0|    }
  501|  1.79k|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|  1.79k|    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.79k|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|  1.79k|    inst->oIndex = i;
  508|  1.79k|    ReadMember(obj, "name", inst->name);
  509|  1.79k|    inst->Read(obj, mAsset);
  510|  1.79k|    inst->ReadExtensions(obj);
  511|  1.79k|    inst->ReadExtras(obj);
  512|       |
  513|  1.79k|    Ref<T> result = Add(inst.release());
  514|  1.79k|    mRecursiveReferenceCheck.erase(i);
  515|  1.79k|    return result;
  516|  1.79k|}
_ZN5glTF28LazyDictINS_4MeshEE3AddEPS1_:
  536|  1.61k|Ref<T> LazyDict<T>::Add(T *obj) {
  537|  1.61k|    unsigned int idx = unsigned(mObjs.size());
  538|  1.61k|    mObjs.push_back(obj);
  539|  1.61k|    mObjsByOIndex[obj->oIndex] = idx;
  540|  1.61k|    mObjsById[obj->id] = idx;
  541|  1.61k|    return Ref<T>(mObjs, idx);
  542|  1.61k|}
_ZN5glTF28LazyDictINS_4SkinEE3GetEj:
  519|    351|Ref<T> LazyDict<T>::Get(unsigned int i) {
  520|    351|    return Ref<T>(mObjs, i);
  521|    351|}
_ZN5glTF28LazyDictINS_5SceneEE8RetrieveEj:
  473|  1.98k|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|  1.98k|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|  1.98k|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 0, False: 1.98k]
  ------------------
  476|      0|        return Ref<T>(mObjs, it->second);
  477|      0|    }
  478|       |
  479|       |    // read it from the JSON object
  480|  1.98k|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 0, False: 1.98k]
  ------------------
  481|      0|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      0|    }
  483|       |
  484|  1.98k|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 1.98k]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|  1.98k|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 0, False: 1.98k]
  ------------------
  489|      0|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|      0|    }
  491|       |
  492|  1.98k|    Value &obj = (*mDict)[i];
  493|       |
  494|  1.98k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 2, False: 1.98k]
  ------------------
  495|      2|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      2|    }
  497|       |
  498|  1.98k|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 0, False: 1.98k]
  ------------------
  499|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|      0|    }
  501|  1.98k|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|  1.98k|    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.98k|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|  1.98k|    inst->oIndex = i;
  508|  1.98k|    ReadMember(obj, "name", inst->name);
  509|  1.98k|    inst->Read(obj, mAsset);
  510|  1.98k|    inst->ReadExtensions(obj);
  511|  1.98k|    inst->ReadExtras(obj);
  512|       |
  513|  1.98k|    Ref<T> result = Add(inst.release());
  514|  1.98k|    mRecursiveReferenceCheck.erase(i);
  515|  1.98k|    return result;
  516|  1.98k|}
_ZN5glTF28LazyDictINS_5SceneEE3AddEPS1_:
  536|  1.72k|Ref<T> LazyDict<T>::Add(T *obj) {
  537|  1.72k|    unsigned int idx = unsigned(mObjs.size());
  538|  1.72k|    mObjs.push_back(obj);
  539|  1.72k|    mObjsByOIndex[obj->oIndex] = idx;
  540|  1.72k|    mObjsById[obj->id] = idx;
  541|  1.72k|    return Ref<T>(mObjs, idx);
  542|  1.72k|}
_ZN5glTF28LazyDictINS_4SkinEE8RetrieveEj:
  473|    389|Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
  474|    389|    typename Dict::iterator it = mObjsByOIndex.find(i);
  475|    389|    if (it != mObjsByOIndex.end()) { // already created?
  ------------------
  |  Branch (475:9): [True: 0, False: 389]
  ------------------
  476|      0|        return Ref<T>(mObjs, it->second);
  477|      0|    }
  478|       |
  479|       |    // read it from the JSON object
  480|    389|    if (!mDict) {
  ------------------
  |  Branch (480:9): [True: 0, False: 389]
  ------------------
  481|      0|        throw DeadlyImportError("GLTF: Missing section \"", mDictId, "\"");
  482|      0|    }
  483|       |
  484|    389|    if (!mDict->IsArray()) {
  ------------------
  |  Branch (484:9): [True: 0, False: 389]
  ------------------
  485|      0|        throw DeadlyImportError("GLTF: Field \"", mDictId, "\"  is not an array");
  486|      0|    }
  487|       |
  488|    389|    if (i >= mDict->Size()) {
  ------------------
  |  Branch (488:9): [True: 0, False: 389]
  ------------------
  489|      0|        throw DeadlyImportError("GLTF: Array index ", i, " is out of bounds (", mDict->Size(), ") for \"", mDictId, "\"");
  490|      0|    }
  491|       |
  492|    389|    Value &obj = (*mDict)[i];
  493|       |
  494|    389|    if (!obj.IsObject()) {
  ------------------
  |  Branch (494:9): [True: 0, False: 389]
  ------------------
  495|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" is not a JSON object");
  496|      0|    }
  497|       |
  498|    389|    if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
  ------------------
  |  Branch (498:9): [True: 0, False: 389]
  ------------------
  499|      0|        throw DeadlyImportError("GLTF: Object at index ", i, " in array \"", mDictId, "\" has recursive reference to itself");
  500|      0|    }
  501|    389|    mRecursiveReferenceCheck.insert(i);
  502|       |
  503|       |    // Unique ptr prevents memory leak in case of Read throws an exception
  504|    389|    auto inst = std::unique_ptr<T>(new T());
  505|       |    // Try to make this human readable so it can be used in error messages.
  506|    389|    inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
  507|    389|    inst->oIndex = i;
  508|    389|    ReadMember(obj, "name", inst->name);
  509|    389|    inst->Read(obj, mAsset);
  510|    389|    inst->ReadExtensions(obj);
  511|    389|    inst->ReadExtras(obj);
  512|       |
  513|    389|    Ref<T> result = Add(inst.release());
  514|    389|    mRecursiveReferenceCheck.erase(i);
  515|    389|    return result;
  516|    389|}
_ZN5glTF28LazyDictINS_4SkinEE3AddEPS1_:
  536|    367|Ref<T> LazyDict<T>::Add(T *obj) {
  537|    367|    unsigned int idx = unsigned(mObjs.size());
  538|    367|    mObjs.push_back(obj);
  539|    367|    mObjsByOIndex[obj->oIndex] = idx;
  540|    367|    mObjsById[obj->id] = idx;
  541|    367|    return Ref<T>(mObjs, idx);
  542|    367|}
_ZN5glTF28LazyDictINS_6BufferEE6CreateEPKc:
  545|  4.22k|Ref<T> LazyDict<T>::Create(const char *id) {
  546|  4.22k|    T *inst = new T();
  547|  4.22k|    unsigned int idx = unsigned(mObjs.size());
  548|  4.22k|    inst->id = id;
  549|  4.22k|    inst->index = idx;
  550|  4.22k|    inst->oIndex = idx;
  551|  4.22k|    return Add(inst);
  552|  4.22k|}
_ZN5glTF28LazyDictINS_8AccessorEEC2ERNS_5AssetEPKcS6_:
  390|  6.32k|        mDictId(dictId),
  391|  6.32k|        mExtId(extId),
  392|  6.32k|        mDict(nullptr),
  393|  6.32k|        mAsset(asset) {
  394|  6.32k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.32k|}
_ZN5glTF28LazyDictINS_9AnimationEEC2ERNS_5AssetEPKcS6_:
  390|  6.32k|        mDictId(dictId),
  391|  6.32k|        mExtId(extId),
  392|  6.32k|        mDict(nullptr),
  393|  6.32k|        mAsset(asset) {
  394|  6.32k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.32k|}
_ZN5glTF28LazyDictINS_6BufferEEC2ERNS_5AssetEPKcS6_:
  390|  6.32k|        mDictId(dictId),
  391|  6.32k|        mExtId(extId),
  392|  6.32k|        mDict(nullptr),
  393|  6.32k|        mAsset(asset) {
  394|  6.32k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.32k|}
_ZN5glTF28LazyDictINS_10BufferViewEEC2ERNS_5AssetEPKcS6_:
  390|  6.32k|        mDictId(dictId),
  391|  6.32k|        mExtId(extId),
  392|  6.32k|        mDict(nullptr),
  393|  6.32k|        mAsset(asset) {
  394|  6.32k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.32k|}
_ZN5glTF28LazyDictINS_6CameraEEC2ERNS_5AssetEPKcS6_:
  390|  6.32k|        mDictId(dictId),
  391|  6.32k|        mExtId(extId),
  392|  6.32k|        mDict(nullptr),
  393|  6.32k|        mAsset(asset) {
  394|  6.32k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.32k|}
_ZN5glTF28LazyDictINS_5LightEEC2ERNS_5AssetEPKcS6_:
  390|  6.32k|        mDictId(dictId),
  391|  6.32k|        mExtId(extId),
  392|  6.32k|        mDict(nullptr),
  393|  6.32k|        mAsset(asset) {
  394|  6.32k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.32k|}
_ZN5glTF28LazyDictINS_5ImageEEC2ERNS_5AssetEPKcS6_:
  390|  6.32k|        mDictId(dictId),
  391|  6.32k|        mExtId(extId),
  392|  6.32k|        mDict(nullptr),
  393|  6.32k|        mAsset(asset) {
  394|  6.32k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.32k|}
_ZN5glTF28LazyDictINS_8MaterialEEC2ERNS_5AssetEPKcS6_:
  390|  6.32k|        mDictId(dictId),
  391|  6.32k|        mExtId(extId),
  392|  6.32k|        mDict(nullptr),
  393|  6.32k|        mAsset(asset) {
  394|  6.32k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.32k|}
_ZN5glTF28LazyDictINS_4MeshEEC2ERNS_5AssetEPKcS6_:
  390|  6.32k|        mDictId(dictId),
  391|  6.32k|        mExtId(extId),
  392|  6.32k|        mDict(nullptr),
  393|  6.32k|        mAsset(asset) {
  394|  6.32k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.32k|}
_ZN5glTF28LazyDictINS_4NodeEEC2ERNS_5AssetEPKcS6_:
  390|  6.32k|        mDictId(dictId),
  391|  6.32k|        mExtId(extId),
  392|  6.32k|        mDict(nullptr),
  393|  6.32k|        mAsset(asset) {
  394|  6.32k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.32k|}
_ZN5glTF28LazyDictINS_7SamplerEEC2ERNS_5AssetEPKcS6_:
  390|  6.32k|        mDictId(dictId),
  391|  6.32k|        mExtId(extId),
  392|  6.32k|        mDict(nullptr),
  393|  6.32k|        mAsset(asset) {
  394|  6.32k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.32k|}
_ZN5glTF28LazyDictINS_5SceneEEC2ERNS_5AssetEPKcS6_:
  390|  6.32k|        mDictId(dictId),
  391|  6.32k|        mExtId(extId),
  392|  6.32k|        mDict(nullptr),
  393|  6.32k|        mAsset(asset) {
  394|  6.32k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.32k|}
_ZN5glTF28LazyDictINS_4SkinEEC2ERNS_5AssetEPKcS6_:
  390|  6.32k|        mDictId(dictId),
  391|  6.32k|        mExtId(extId),
  392|  6.32k|        mDict(nullptr),
  393|  6.32k|        mAsset(asset) {
  394|  6.32k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.32k|}
_ZN5glTF28LazyDictINS_7TextureEEC2ERNS_5AssetEPKcS6_:
  390|  6.32k|        mDictId(dictId),
  391|  6.32k|        mExtId(extId),
  392|  6.32k|        mDict(nullptr),
  393|  6.32k|        mAsset(asset) {
  394|  6.32k|    asset.mDicts.push_back(this); // register to the list of dictionaries
  395|  6.32k|}
_ZN5glTF28LazyDictINS_7TextureEED2Ev:
  398|  6.32k|inline LazyDict<T>::~LazyDict() {
  399|  6.38k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 63, False: 6.32k]
  ------------------
  400|     63|        delete mObjs[i];
  401|     63|    }
  402|  6.32k|}
_ZN5glTF28LazyDictINS_4SkinEED2Ev:
  398|  6.32k|inline LazyDict<T>::~LazyDict() {
  399|  6.69k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 367, False: 6.32k]
  ------------------
  400|    367|        delete mObjs[i];
  401|    367|    }
  402|  6.32k|}
_ZN5glTF28LazyDictINS_5SceneEED2Ev:
  398|  6.32k|inline LazyDict<T>::~LazyDict() {
  399|  8.05k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 1.72k, False: 6.32k]
  ------------------
  400|  1.72k|        delete mObjs[i];
  401|  1.72k|    }
  402|  6.32k|}
_ZN5glTF28LazyDictINS_7SamplerEED2Ev:
  398|  6.32k|inline LazyDict<T>::~LazyDict() {
  399|  6.38k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 58, False: 6.32k]
  ------------------
  400|     58|        delete mObjs[i];
  401|     58|    }
  402|  6.32k|}
_ZN5glTF28LazyDictINS_4NodeEED2Ev:
  398|  6.32k|inline LazyDict<T>::~LazyDict() {
  399|  17.6k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 11.3k, False: 6.32k]
  ------------------
  400|  11.3k|        delete mObjs[i];
  401|  11.3k|    }
  402|  6.32k|}
_ZN5glTF28LazyDictINS_4MeshEED2Ev:
  398|  6.32k|inline LazyDict<T>::~LazyDict() {
  399|  7.93k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 1.61k, False: 6.32k]
  ------------------
  400|  1.61k|        delete mObjs[i];
  401|  1.61k|    }
  402|  6.32k|}
_ZN5glTF28LazyDictINS_8MaterialEED2Ev:
  398|  6.32k|inline LazyDict<T>::~LazyDict() {
  399|  7.73k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 1.41k, False: 6.32k]
  ------------------
  400|  1.41k|        delete mObjs[i];
  401|  1.41k|    }
  402|  6.32k|}
_ZN5glTF28LazyDictINS_5ImageEED2Ev:
  398|  6.32k|inline LazyDict<T>::~LazyDict() {
  399|  6.38k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 57, False: 6.32k]
  ------------------
  400|     57|        delete mObjs[i];
  401|     57|    }
  402|  6.32k|}
_ZN5glTF28LazyDictINS_5LightEED2Ev:
  398|  6.32k|inline LazyDict<T>::~LazyDict() {
  399|  6.32k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 0, False: 6.32k]
  ------------------
  400|      0|        delete mObjs[i];
  401|      0|    }
  402|  6.32k|}
_ZN5glTF28LazyDictINS_6CameraEED2Ev:
  398|  6.32k|inline LazyDict<T>::~LazyDict() {
  399|  6.32k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 0, False: 6.32k]
  ------------------
  400|      0|        delete mObjs[i];
  401|      0|    }
  402|  6.32k|}
_ZN5glTF28LazyDictINS_10BufferViewEED2Ev:
  398|  6.32k|inline LazyDict<T>::~LazyDict() {
  399|  12.9k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 6.65k, False: 6.32k]
  ------------------
  400|  6.65k|        delete mObjs[i];
  401|  6.65k|    }
  402|  6.32k|}
_ZN5glTF28LazyDictINS_6BufferEED2Ev:
  398|  6.32k|inline LazyDict<T>::~LazyDict() {
  399|  10.5k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 4.22k, False: 6.32k]
  ------------------
  400|  4.22k|        delete mObjs[i];
  401|  4.22k|    }
  402|  6.32k|}
_ZN5glTF28LazyDictINS_9AnimationEED2Ev:
  398|  6.32k|inline LazyDict<T>::~LazyDict() {
  399|  6.32k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 0, False: 6.32k]
  ------------------
  400|      0|        delete mObjs[i];
  401|      0|    }
  402|  6.32k|}
_ZN5glTF28LazyDictINS_8AccessorEED2Ev:
  398|  6.32k|inline LazyDict<T>::~LazyDict() {
  399|  13.3k|    for (size_t i = 0; i < mObjs.size(); ++i) {
  ------------------
  |  Branch (399:24): [True: 6.98k, False: 6.32k]
  ------------------
  400|  6.98k|        delete mObjs[i];
  401|  6.98k|    }
  402|  6.32k|}
_ZN5glTF26BufferC2Ev:
  558|  4.22k|        byteLength(0),
  559|  4.22k|        type(Type_arraybuffer),
  560|  4.22k|        EncodedRegion_Current(nullptr),
  561|  4.22k|        mIsSpecial(false) {
  562|       |    // empty
  563|  4.22k|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_19SetVectorERA4_fRA4_Kf:
  176|  7.89k|void SetVector(vec4 &v, const float (&in)[4]) {
  177|  7.89k|    v[0] = in[0];
  178|  7.89k|    v[1] = in[1];
  179|  7.89k|    v[2] = in[2];
  180|  7.89k|    v[3] = in[3];
  181|  7.89k|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_19SetVectorERA3_fRA3_Kf:
  183|  17.5k|void SetVector(vec3 &v, const float (&in)[3]) {
  184|  17.5k|    v[0] = in[0];
  185|  17.5k|    v[1] = in[1];
  186|  17.5k|    v[2] = in[2];
  187|  17.5k|}
_ZN5glTF28Accessor7IndexerC2ERS0_:
 1109|    956|    accessor(acc),
 1110|    956|    data(acc.GetPointer()),
 1111|    956|    elemSize(acc.GetElementSize()),
 1112|    956|    stride(acc.GetStride()) {
 1113|    956|}
glTF2Importer.cpp:_ZN5glTF28Accessor11ExtractDataIZL24BuildVertexWeightMappingRNS_4Mesh9PrimitiveERNSt3__16vectorINS6_I14aiVertexWeightNS5_9allocatorIS7_EEEENS8_ISA_EEEEPNS6_IjNS8_IjEEEEE7WeightsEEmRPT_PKSF_:
 1021|    823|size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
 1022|    823|    uint8_t *data = GetPointer();
 1023|    823|    if (!data) {
  ------------------
  |  Branch (1023:9): [True: 6, False: 817]
  ------------------
 1024|      6|        throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
 1025|      6|    }
 1026|       |
 1027|    817|    const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
  ------------------
  |  Branch (1027:30): [True: 638, False: 179]
  ------------------
 1028|    817|    const size_t elemSize = GetElementSize();
 1029|    817|    const size_t totalSize = elemSize * usedCount;
 1030|       |
 1031|    817|    const size_t stride = GetStride();
 1032|       |
 1033|    817|    const size_t targetElemSize = sizeof(T);
 1034|       |
 1035|    817|    if (elemSize > targetElemSize) {
  ------------------
  |  Branch (1035:9): [True: 1, False: 816]
  ------------------
 1036|      1|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > targetElemSize ", targetElemSize, " in ", getContextForErrorMessages(id, name));
 1037|      1|    }
 1038|       |
 1039|    816|    const size_t maxSize = GetMaxByteSize();
 1040|       |
 1041|    816|    outData = new T[usedCount];
 1042|       |
 1043|    816|    if (remappingIndices != nullptr) {
  ------------------
  |  Branch (1043:9): [True: 637, False: 179]
  ------------------
 1044|    637|        const unsigned int maxIndexCount = static_cast<unsigned int>(maxSize / stride);
 1045|  2.73k|        for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1045:28): [True: 2.09k, False: 637]
  ------------------
 1046|  2.09k|            size_t srcIdx = (*remappingIndices)[i];
 1047|  2.09k|            if (srcIdx >= maxIndexCount) {
  ------------------
  |  Branch (1047:17): [True: 0, False: 2.09k]
  ------------------
 1048|      0|                throw DeadlyImportError("GLTF: index*stride ", (srcIdx * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1049|      0|            }
 1050|  2.09k|            memcpy(outData + i, data + srcIdx * stride, elemSize);
 1051|  2.09k|        }
 1052|    637|    } else { // non-indexed cases
 1053|    179|        if (usedCount * stride > maxSize) {
  ------------------
  |  Branch (1053:13): [True: 0, False: 179]
  ------------------
 1054|      0|            throw DeadlyImportError("GLTF: count*stride ", (usedCount * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1055|      0|        }
 1056|    179|        if (stride == elemSize && targetElemSize == elemSize) {
  ------------------
  |  Branch (1056:13): [True: 179, False: 0]
  |  Branch (1056:35): [True: 139, False: 40]
  ------------------
 1057|    139|            memcpy(outData, data, totalSize);
 1058|    139|        } else {
 1059|    196|            for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1059:32): [True: 156, False: 40]
  ------------------
 1060|    156|                memcpy(outData + i, data + i * stride, elemSize);
 1061|    156|            }
 1062|     40|        }
 1063|    179|    }
 1064|    816|    return usedCount;
 1065|    816|}
glTF2Importer.cpp:_ZN5glTF28Accessor11ExtractDataIZL24BuildVertexWeightMappingRNS_4Mesh9PrimitiveERNSt3__16vectorINS6_I14aiVertexWeightNS5_9allocatorIS7_EEEENS8_ISA_EEEEPNS6_IjNS8_IjEEEEE8Indices8EEmRPT_PKSF_:
 1021|     85|size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
 1022|     85|    uint8_t *data = GetPointer();
 1023|     85|    if (!data) {
  ------------------
  |  Branch (1023:9): [True: 8, False: 77]
  ------------------
 1024|      8|        throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
 1025|      8|    }
 1026|       |
 1027|     77|    const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
  ------------------
  |  Branch (1027:30): [True: 32, False: 45]
  ------------------
 1028|     77|    const size_t elemSize = GetElementSize();
 1029|     77|    const size_t totalSize = elemSize * usedCount;
 1030|       |
 1031|     77|    const size_t stride = GetStride();
 1032|       |
 1033|     77|    const size_t targetElemSize = sizeof(T);
 1034|       |
 1035|     77|    if (elemSize > targetElemSize) {
  ------------------
  |  Branch (1035:9): [True: 13, False: 64]
  ------------------
 1036|     13|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > targetElemSize ", targetElemSize, " in ", getContextForErrorMessages(id, name));
 1037|     13|    }
 1038|       |
 1039|     64|    const size_t maxSize = GetMaxByteSize();
 1040|       |
 1041|     64|    outData = new T[usedCount];
 1042|       |
 1043|     64|    if (remappingIndices != nullptr) {
  ------------------
  |  Branch (1043:9): [True: 23, False: 41]
  ------------------
 1044|     23|        const unsigned int maxIndexCount = static_cast<unsigned int>(maxSize / stride);
 1045|     89|        for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1045:28): [True: 66, False: 23]
  ------------------
 1046|     66|            size_t srcIdx = (*remappingIndices)[i];
 1047|     66|            if (srcIdx >= maxIndexCount) {
  ------------------
  |  Branch (1047:17): [True: 0, False: 66]
  ------------------
 1048|      0|                throw DeadlyImportError("GLTF: index*stride ", (srcIdx * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1049|      0|            }
 1050|     66|            memcpy(outData + i, data + srcIdx * stride, elemSize);
 1051|     66|        }
 1052|     41|    } else { // non-indexed cases
 1053|     41|        if (usedCount * stride > maxSize) {
  ------------------
  |  Branch (1053:13): [True: 0, False: 41]
  ------------------
 1054|      0|            throw DeadlyImportError("GLTF: count*stride ", (usedCount * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1055|      0|        }
 1056|     41|        if (stride == elemSize && targetElemSize == elemSize) {
  ------------------
  |  Branch (1056:13): [True: 41, False: 0]
  |  Branch (1056:35): [True: 27, False: 14]
  ------------------
 1057|     27|            memcpy(outData, data, totalSize);
 1058|     27|        } else {
 1059|     74|            for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1059:32): [True: 60, False: 14]
  ------------------
 1060|     60|                memcpy(outData + i, data + i * stride, elemSize);
 1061|     60|            }
 1062|     14|        }
 1063|     41|    }
 1064|     64|    return usedCount;
 1065|     64|}
glTF2Importer.cpp:_ZN5glTF28Accessor11ExtractDataIZL24BuildVertexWeightMappingRNS_4Mesh9PrimitiveERNSt3__16vectorINS6_I14aiVertexWeightNS5_9allocatorIS7_EEEENS8_ISA_EEEEPNS6_IjNS8_IjEEEEE9Indices16EEmRPT_PKSF_:
 1021|    716|size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
 1022|    716|    uint8_t *data = GetPointer();
 1023|    716|    if (!data) {
  ------------------
  |  Branch (1023:9): [True: 7, False: 709]
  ------------------
 1024|      7|        throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
 1025|      7|    }
 1026|       |
 1027|    709|    const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
  ------------------
  |  Branch (1027:30): [True: 595, False: 114]
  ------------------
 1028|    709|    const size_t elemSize = GetElementSize();
 1029|    709|    const size_t totalSize = elemSize * usedCount;
 1030|       |
 1031|    709|    const size_t stride = GetStride();
 1032|       |
 1033|    709|    const size_t targetElemSize = sizeof(T);
 1034|       |
 1035|    709|    if (elemSize > targetElemSize) {
  ------------------
  |  Branch (1035:9): [True: 2, False: 707]
  ------------------
 1036|      2|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > targetElemSize ", targetElemSize, " in ", getContextForErrorMessages(id, name));
 1037|      2|    }
 1038|       |
 1039|    707|    const size_t maxSize = GetMaxByteSize();
 1040|       |
 1041|    707|    outData = new T[usedCount];
 1042|       |
 1043|    707|    if (remappingIndices != nullptr) {
  ------------------
  |  Branch (1043:9): [True: 593, False: 114]
  ------------------
 1044|    593|        const unsigned int maxIndexCount = static_cast<unsigned int>(maxSize / stride);
 1045|  2.54k|        for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1045:28): [True: 1.94k, False: 593]
  ------------------
 1046|  1.94k|            size_t srcIdx = (*remappingIndices)[i];
 1047|  1.94k|            if (srcIdx >= maxIndexCount) {
  ------------------
  |  Branch (1047:17): [True: 0, False: 1.94k]
  ------------------
 1048|      0|                throw DeadlyImportError("GLTF: index*stride ", (srcIdx * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1049|      0|            }
 1050|  1.94k|            memcpy(outData + i, data + srcIdx * stride, elemSize);
 1051|  1.94k|        }
 1052|    593|    } else { // non-indexed cases
 1053|    114|        if (usedCount * stride > maxSize) {
  ------------------
  |  Branch (1053:13): [True: 0, False: 114]
  ------------------
 1054|      0|            throw DeadlyImportError("GLTF: count*stride ", (usedCount * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1055|      0|        }
 1056|    114|        if (stride == elemSize && targetElemSize == elemSize) {
  ------------------
  |  Branch (1056:13): [True: 114, False: 0]
  |  Branch (1056:35): [True: 71, False: 43]
  ------------------
 1057|     71|            memcpy(outData, data, totalSize);
 1058|     71|        } else {
 1059|    249|            for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1059:32): [True: 206, False: 43]
  ------------------
 1060|    206|                memcpy(outData + i, data + i * stride, elemSize);
 1061|    206|            }
 1062|     43|        }
 1063|    114|    }
 1064|    707|    return usedCount;
 1065|    707|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_114ReadExtensionsEPKcRN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEE:
  110|  33.2k|inline CustomExtension ReadExtensions(const char *name, Value &obj) {
  111|  33.2k|    CustomExtension ret;
  112|  33.2k|    ret.name = name;
  113|  33.2k|    if (obj.IsObject()) {
  ------------------
  |  Branch (113:9): [True: 14, False: 33.2k]
  ------------------
  114|     14|        ret.mValues.isPresent = true;
  115|     72|        for (auto it = obj.MemberBegin(); it != obj.MemberEnd(); ++it) {
  ------------------
  |  Branch (115:43): [True: 58, False: 14]
  ------------------
  116|     58|            auto &val = it->value;
  117|     58|            ret.mValues.value.push_back(ReadExtensions(it->name.GetString(), val));
  118|     58|        }
  119|  33.2k|    } else if (obj.IsArray()) {
  ------------------
  |  Branch (119:16): [True: 34, False: 33.1k]
  ------------------
  120|     34|        ret.mValues.value.reserve(obj.Size());
  121|     34|        ret.mValues.isPresent = true;
  122|     83|        for (unsigned int i = 0; i < obj.Size(); ++i) {
  ------------------
  |  Branch (122:34): [True: 49, False: 34]
  ------------------
  123|     49|            ret.mValues.value.push_back(ReadExtensions(name, obj[i]));
  124|     49|        }
  125|  33.1k|    } else if (obj.IsNumber()) {
  ------------------
  |  Branch (125:16): [True: 16.8k, False: 16.3k]
  ------------------
  126|  16.8k|        if (obj.IsUint64()) {
  ------------------
  |  Branch (126:13): [True: 16.8k, False: 25]
  ------------------
  127|  16.8k|            ret.mUint64Value.value = obj.GetUint64();
  128|  16.8k|            ret.mUint64Value.isPresent = true;
  129|  16.8k|        } else if (obj.IsInt64()) {
  ------------------
  |  Branch (129:20): [True: 7, False: 18]
  ------------------
  130|      7|            ret.mInt64Value.value = obj.GetInt64();
  131|      7|            ret.mInt64Value.isPresent = true;
  132|     18|        } else if (obj.IsDouble()) {
  ------------------
  |  Branch (132:20): [True: 18, False: 0]
  ------------------
  133|     18|            ret.mDoubleValue.value = obj.GetDouble();
  134|     18|            ret.mDoubleValue.isPresent = true;
  135|     18|        }
  136|  16.8k|    } else if (obj.IsString()) {
  ------------------
  |  Branch (136:16): [True: 8.18k, False: 8.17k]
  ------------------
  137|  8.18k|        ReadValue(obj, ret.mStringValue);
  138|  8.18k|        ret.mStringValue.isPresent = true;
  139|  8.18k|    } else if (obj.IsBool()) {
  ------------------
  |  Branch (139:16): [True: 8.17k, False: 0]
  ------------------
  140|  8.17k|        ret.mBoolValue.value = obj.GetBool();
  141|  8.17k|        ret.mBoolValue.isPresent = true;
  142|  8.17k|    }
  143|  33.2k|    return ret;
  144|  33.2k|}
_ZN5glTF25ImageC2Ev:
 1131|     60|        width(0),
 1132|     60|        height(0),
 1133|     60|        mDataLength(0) {
 1134|     60|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_115GetAttribVectorERNS_4Mesh9PrimitiveEPKcRPNSt3__16vectorIN10glTFCommon3RefINS_8AccessorEEENS6_9allocatorISB_EEEERi:
  199|  6.35k|inline bool GetAttribVector(Mesh::Primitive &p, const char *attr, Mesh::AccessorList *&v, int &pos) {
  200|  6.35k|    if ((pos = Compare(attr, "POSITION"))) {
  ------------------
  |  Branch (200:9): [True: 1.58k, False: 4.76k]
  ------------------
  201|  1.58k|        v = &(p.attributes.position);
  202|  4.76k|    } else if ((pos = Compare(attr, "NORMAL"))) {
  ------------------
  |  Branch (202:16): [True: 1.26k, False: 3.50k]
  ------------------
  203|  1.26k|        v = &(p.attributes.normal);
  204|  3.50k|    } else if ((pos = Compare(attr, "TANGENT"))) {
  ------------------
  |  Branch (204:16): [True: 53, False: 3.45k]
  ------------------
  205|     53|        v = &(p.attributes.tangent);
  206|  3.45k|    } else if ((pos = Compare(attr, "TEXCOORD"))) {
  ------------------
  |  Branch (206:16): [True: 536, False: 2.91k]
  ------------------
  207|    536|        v = &(p.attributes.texcoord);
  208|  2.91k|    } else if ((pos = Compare(attr, "COLOR"))) {
  ------------------
  |  Branch (208:16): [True: 404, False: 2.51k]
  ------------------
  209|    404|        v = &(p.attributes.color);
  210|  2.51k|    } else if ((pos = Compare(attr, "JOINTS"))) {
  ------------------
  |  Branch (210:16): [True: 1.05k, False: 1.46k]
  ------------------
  211|  1.05k|        v = &(p.attributes.joint);
  212|  1.46k|    } else if ((pos = Compare(attr, "JOINTMATRIX"))) {
  ------------------
  |  Branch (212:16): [True: 0, False: 1.46k]
  ------------------
  213|      0|        v = &(p.attributes.jointmatrix);
  214|  1.46k|    } else if ((pos = Compare(attr, "WEIGHTS"))) {
  ------------------
  |  Branch (214:16): [True: 1.00k, False: 458]
  ------------------
  215|  1.00k|        v = &(p.attributes.weight);
  216|  1.00k|    } else
  217|    458|        return false;
  218|  5.89k|    return true;
  219|  6.35k|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_17CompareILi9EEEiPKcRAT__S2_:
  190|  9.80k|inline int Compare(const char *attr, const char (&str)[N]) {
  191|  9.80k|    return (strncmp(attr, str, N - 1) == 0) ? N - 1 : 0;
  ------------------
  |  Branch (191:12): [True: 2.12k, False: 7.68k]
  ------------------
  192|  9.80k|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_17CompareILi7EEEiPKcRAT__S2_:
  190|  7.27k|inline int Compare(const char *attr, const char (&str)[N]) {
  191|  7.27k|    return (strncmp(attr, str, N - 1) == 0) ? N - 1 : 0;
  ------------------
  |  Branch (191:12): [True: 2.31k, False: 4.96k]
  ------------------
  192|  7.27k|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_17CompareILi8EEEiPKcRAT__S2_:
  190|  4.96k|inline int Compare(const char *attr, const char (&str)[N]) {
  191|  4.96k|    return (strncmp(attr, str, N - 1) == 0) ? N - 1 : 0;
  ------------------
  |  Branch (191:12): [True: 1.05k, False: 3.91k]
  ------------------
  192|  4.96k|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_17CompareILi6EEEiPKcRAT__S2_:
  190|  2.91k|inline int Compare(const char *attr, const char (&str)[N]) {
  191|  2.91k|    return (strncmp(attr, str, N - 1) == 0) ? N - 1 : 0;
  ------------------
  |  Branch (191:12): [True: 404, False: 2.51k]
  ------------------
  192|  2.91k|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_17CompareILi12EEEiPKcRAT__S2_:
  190|  1.46k|inline int Compare(const char *attr, const char (&str)[N]) {
  191|  1.46k|    return (strncmp(attr, str, N - 1) == 0) ? N - 1 : 0;
  ------------------
  |  Branch (191:12): [True: 0, False: 1.46k]
  ------------------
  192|  1.46k|}
glTF2Importer.cpp:_ZN5glTF212_GLOBAL__N_110ReadExtrasERN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEE:
  146|  8.23k|inline Extras ReadExtras(Value &obj) {
  147|  8.23k|    Extras ret;
  148|       |
  149|  8.23k|    ret.mValues.reserve(obj.MemberCount());
  150|  41.3k|    for (auto it = obj.MemberBegin(); it != obj.MemberEnd(); ++it) {
  ------------------
  |  Branch (150:39): [True: 33.1k, False: 8.23k]
  ------------------
  151|  33.1k|        auto &val = it->value;
  152|  33.1k|        ret.mValues.emplace_back(ReadExtensions(it->name.GetString(), val));
  153|  33.1k|    }
  154|       |
  155|  8.23k|    return ret;
  156|  8.23k|}
_ZN5glTF28Accessor11ExtractDataI10aiVector3tIfEEEmRPT_PKNSt3__16vectorIjNS7_9allocatorIjEEEE:
 1021|  2.85k|size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
 1022|  2.85k|    uint8_t *data = GetPointer();
 1023|  2.85k|    if (!data) {
  ------------------
  |  Branch (1023:9): [True: 14, False: 2.84k]
  ------------------
 1024|     14|        throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
 1025|     14|    }
 1026|       |
 1027|  2.84k|    const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
  ------------------
  |  Branch (1027:30): [True: 1.87k, False: 962]
  ------------------
 1028|  2.84k|    const size_t elemSize = GetElementSize();
 1029|  2.84k|    const size_t totalSize = elemSize * usedCount;
 1030|       |
 1031|  2.84k|    const size_t stride = GetStride();
 1032|       |
 1033|  2.84k|    const size_t targetElemSize = sizeof(T);
 1034|       |
 1035|  2.84k|    if (elemSize > targetElemSize) {
  ------------------
  |  Branch (1035:9): [True: 1, False: 2.84k]
  ------------------
 1036|      1|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > targetElemSize ", targetElemSize, " in ", getContextForErrorMessages(id, name));
 1037|      1|    }
 1038|       |
 1039|  2.84k|    const size_t maxSize = GetMaxByteSize();
 1040|       |
 1041|  2.84k|    outData = new T[usedCount];
 1042|       |
 1043|  2.84k|    if (remappingIndices != nullptr) {
  ------------------
  |  Branch (1043:9): [True: 1.87k, False: 961]
  ------------------
 1044|  1.87k|        const unsigned int maxIndexCount = static_cast<unsigned int>(maxSize / stride);
 1045|  14.9k|        for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1045:28): [True: 13.0k, False: 1.87k]
  ------------------
 1046|  13.0k|            size_t srcIdx = (*remappingIndices)[i];
 1047|  13.0k|            if (srcIdx >= maxIndexCount) {
  ------------------
  |  Branch (1047:17): [True: 2, False: 13.0k]
  ------------------
 1048|      2|                throw DeadlyImportError("GLTF: index*stride ", (srcIdx * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1049|      2|            }
 1050|  13.0k|            memcpy(outData + i, data + srcIdx * stride, elemSize);
 1051|  13.0k|        }
 1052|  1.87k|    } else { // non-indexed cases
 1053|    961|        if (usedCount * stride > maxSize) {
  ------------------
  |  Branch (1053:13): [True: 2, False: 959]
  ------------------
 1054|      2|            throw DeadlyImportError("GLTF: count*stride ", (usedCount * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1055|      2|        }
 1056|    959|        if (stride == elemSize && targetElemSize == elemSize) {
  ------------------
  |  Branch (1056:13): [True: 700, False: 259]
  |  Branch (1056:35): [True: 301, False: 399]
  ------------------
 1057|    301|            memcpy(outData, data, totalSize);
 1058|    658|        } else {
 1059|  26.0k|            for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1059:32): [True: 25.3k, False: 658]
  ------------------
 1060|  25.3k|                memcpy(outData + i, data + i * stride, elemSize);
 1061|  25.3k|            }
 1062|    658|        }
 1063|    959|    }
 1064|  2.83k|    return usedCount;
 1065|  2.84k|}
glTF2Importer.cpp:_ZN5glTF28Accessor11ExtractDataIN12_GLOBAL__N_17TangentEEEmRPT_PKNSt3__16vectorIjNS7_9allocatorIjEEEE:
 1021|     39|size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
 1022|     39|    uint8_t *data = GetPointer();
 1023|     39|    if (!data) {
  ------------------
  |  Branch (1023:9): [True: 1, False: 38]
  ------------------
 1024|      1|        throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
 1025|      1|    }
 1026|       |
 1027|     38|    const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
  ------------------
  |  Branch (1027:30): [True: 24, False: 14]
  ------------------
 1028|     38|    const size_t elemSize = GetElementSize();
 1029|     38|    const size_t totalSize = elemSize * usedCount;
 1030|       |
 1031|     38|    const size_t stride = GetStride();
 1032|       |
 1033|     38|    const size_t targetElemSize = sizeof(T);
 1034|       |
 1035|     38|    if (elemSize > targetElemSize) {
  ------------------
  |  Branch (1035:9): [True: 0, False: 38]
  ------------------
 1036|      0|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > targetElemSize ", targetElemSize, " in ", getContextForErrorMessages(id, name));
 1037|      0|    }
 1038|       |
 1039|     38|    const size_t maxSize = GetMaxByteSize();
 1040|       |
 1041|     38|    outData = new T[usedCount];
 1042|       |
 1043|     38|    if (remappingIndices != nullptr) {
  ------------------
  |  Branch (1043:9): [True: 24, False: 14]
  ------------------
 1044|     24|        const unsigned int maxIndexCount = static_cast<unsigned int>(maxSize / stride);
 1045|    161|        for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1045:28): [True: 137, False: 24]
  ------------------
 1046|    137|            size_t srcIdx = (*remappingIndices)[i];
 1047|    137|            if (srcIdx >= maxIndexCount) {
  ------------------
  |  Branch (1047:17): [True: 0, False: 137]
  ------------------
 1048|      0|                throw DeadlyImportError("GLTF: index*stride ", (srcIdx * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1049|      0|            }
 1050|    137|            memcpy(outData + i, data + srcIdx * stride, elemSize);
 1051|    137|        }
 1052|     24|    } else { // non-indexed cases
 1053|     14|        if (usedCount * stride > maxSize) {
  ------------------
  |  Branch (1053:13): [True: 0, False: 14]
  ------------------
 1054|      0|            throw DeadlyImportError("GLTF: count*stride ", (usedCount * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1055|      0|        }
 1056|     14|        if (stride == elemSize && targetElemSize == elemSize) {
  ------------------
  |  Branch (1056:13): [True: 12, False: 2]
  |  Branch (1056:35): [True: 2, False: 10]
  ------------------
 1057|      2|            memcpy(outData, data, totalSize);
 1058|     12|        } else {
 1059|    300|            for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1059:32): [True: 288, False: 12]
  ------------------
 1060|    288|                memcpy(outData + i, data + i * stride, elemSize);
 1061|    288|            }
 1062|     12|        }
 1063|     14|    }
 1064|     38|    return usedCount;
 1065|     38|}
_ZN5glTF28Accessor11ExtractDataI9aiColor4tIfEEEmRPT_PKNSt3__16vectorIjNS7_9allocatorIjEEEE:
 1021|    297|size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
 1022|    297|    uint8_t *data = GetPointer();
 1023|    297|    if (!data) {
  ------------------
  |  Branch (1023:9): [True: 3, False: 294]
  ------------------
 1024|      3|        throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
 1025|      3|    }
 1026|       |
 1027|    294|    const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
  ------------------
  |  Branch (1027:30): [True: 225, False: 69]
  ------------------
 1028|    294|    const size_t elemSize = GetElementSize();
 1029|    294|    const size_t totalSize = elemSize * usedCount;
 1030|       |
 1031|    294|    const size_t stride = GetStride();
 1032|       |
 1033|    294|    const size_t targetElemSize = sizeof(T);
 1034|       |
 1035|    294|    if (elemSize > targetElemSize) {
  ------------------
  |  Branch (1035:9): [True: 0, False: 294]
  ------------------
 1036|      0|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > targetElemSize ", targetElemSize, " in ", getContextForErrorMessages(id, name));
 1037|      0|    }
 1038|       |
 1039|    294|    const size_t maxSize = GetMaxByteSize();
 1040|       |
 1041|    294|    outData = new T[usedCount];
 1042|       |
 1043|    294|    if (remappingIndices != nullptr) {
  ------------------
  |  Branch (1043:9): [True: 225, False: 69]
  ------------------
 1044|    225|        const unsigned int maxIndexCount = static_cast<unsigned int>(maxSize / stride);
 1045|  1.01k|        for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1045:28): [True: 789, False: 225]
  ------------------
 1046|    789|            size_t srcIdx = (*remappingIndices)[i];
 1047|    789|            if (srcIdx >= maxIndexCount) {
  ------------------
  |  Branch (1047:17): [True: 0, False: 789]
  ------------------
 1048|      0|                throw DeadlyImportError("GLTF: index*stride ", (srcIdx * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1049|      0|            }
 1050|    789|            memcpy(outData + i, data + srcIdx * stride, elemSize);
 1051|    789|        }
 1052|    225|    } else { // non-indexed cases
 1053|     69|        if (usedCount * stride > maxSize) {
  ------------------
  |  Branch (1053:13): [True: 1, False: 68]
  ------------------
 1054|      1|            throw DeadlyImportError("GLTF: count*stride ", (usedCount * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1055|      1|        }
 1056|     68|        if (stride == elemSize && targetElemSize == elemSize) {
  ------------------
  |  Branch (1056:13): [True: 55, False: 13]
  |  Branch (1056:35): [True: 47, False: 8]
  ------------------
 1057|     47|            memcpy(outData, data, totalSize);
 1058|     47|        } else {
 1059|    485|            for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1059:32): [True: 464, False: 21]
  ------------------
 1060|    464|                memcpy(outData + i, data + i * stride, elemSize);
 1061|    464|            }
 1062|     21|        }
 1063|     68|    }
 1064|    293|    return usedCount;
 1065|    294|}
_ZN5glTF28Accessor11ExtractDataI9aiColor4tIhEEEmRPT_PKNSt3__16vectorIjNS7_9allocatorIjEEEE:
 1021|      9|size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
 1022|      9|    uint8_t *data = GetPointer();
 1023|      9|    if (!data) {
  ------------------
  |  Branch (1023:9): [True: 1, False: 8]
  ------------------
 1024|      1|        throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
 1025|      1|    }
 1026|       |
 1027|      8|    const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
  ------------------
  |  Branch (1027:30): [True: 5, False: 3]
  ------------------
 1028|      8|    const size_t elemSize = GetElementSize();
 1029|      8|    const size_t totalSize = elemSize * usedCount;
 1030|       |
 1031|      8|    const size_t stride = GetStride();
 1032|       |
 1033|      8|    const size_t targetElemSize = sizeof(T);
 1034|       |
 1035|      8|    if (elemSize > targetElemSize) {
  ------------------
  |  Branch (1035:9): [True: 0, False: 8]
  ------------------
 1036|      0|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > targetElemSize ", targetElemSize, " in ", getContextForErrorMessages(id, name));
 1037|      0|    }
 1038|       |
 1039|      8|    const size_t maxSize = GetMaxByteSize();
 1040|       |
 1041|      8|    outData = new T[usedCount];
 1042|       |
 1043|      8|    if (remappingIndices != nullptr) {
  ------------------
  |  Branch (1043:9): [True: 5, False: 3]
  ------------------
 1044|      5|        const unsigned int maxIndexCount = static_cast<unsigned int>(maxSize / stride);
 1045|     15|        for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1045:28): [True: 10, False: 5]
  ------------------
 1046|     10|            size_t srcIdx = (*remappingIndices)[i];
 1047|     10|            if (srcIdx >= maxIndexCount) {
  ------------------
  |  Branch (1047:17): [True: 0, False: 10]
  ------------------
 1048|      0|                throw DeadlyImportError("GLTF: index*stride ", (srcIdx * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1049|      0|            }
 1050|     10|            memcpy(outData + i, data + srcIdx * stride, elemSize);
 1051|     10|        }
 1052|      5|    } else { // non-indexed cases
 1053|      3|        if (usedCount * stride > maxSize) {
  ------------------
  |  Branch (1053:13): [True: 0, False: 3]
  ------------------
 1054|      0|            throw DeadlyImportError("GLTF: count*stride ", (usedCount * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1055|      0|        }
 1056|      3|        if (stride == elemSize && targetElemSize == elemSize) {
  ------------------
  |  Branch (1056:13): [True: 3, False: 0]
  |  Branch (1056:35): [True: 1, False: 2]
  ------------------
 1057|      1|            memcpy(outData, data, totalSize);
 1058|      2|        } else {
 1059|     10|            for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1059:32): [True: 8, False: 2]
  ------------------
 1060|      8|                memcpy(outData + i, data + i * stride, elemSize);
 1061|      8|            }
 1062|      2|        }
 1063|      3|    }
 1064|      8|    return usedCount;
 1065|      8|}
_ZN5glTF28Accessor11ExtractDataI9aiColor4tItEEEmRPT_PKNSt3__16vectorIjNS7_9allocatorIjEEEE:
 1021|     11|size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
 1022|     11|    uint8_t *data = GetPointer();
 1023|     11|    if (!data) {
  ------------------
  |  Branch (1023:9): [True: 1, False: 10]
  ------------------
 1024|      1|        throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
 1025|      1|    }
 1026|       |
 1027|     10|    const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
  ------------------
  |  Branch (1027:30): [True: 6, False: 4]
  ------------------
 1028|     10|    const size_t elemSize = GetElementSize();
 1029|     10|    const size_t totalSize = elemSize * usedCount;
 1030|       |
 1031|     10|    const size_t stride = GetStride();
 1032|       |
 1033|     10|    const size_t targetElemSize = sizeof(T);
 1034|       |
 1035|     10|    if (elemSize > targetElemSize) {
  ------------------
  |  Branch (1035:9): [True: 0, False: 10]
  ------------------
 1036|      0|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > targetElemSize ", targetElemSize, " in ", getContextForErrorMessages(id, name));
 1037|      0|    }
 1038|       |
 1039|     10|    const size_t maxSize = GetMaxByteSize();
 1040|       |
 1041|     10|    outData = new T[usedCount];
 1042|       |
 1043|     10|    if (remappingIndices != nullptr) {
  ------------------
  |  Branch (1043:9): [True: 6, False: 4]
  ------------------
 1044|      6|        const unsigned int maxIndexCount = static_cast<unsigned int>(maxSize / stride);
 1045|     19|        for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1045:28): [True: 13, False: 6]
  ------------------
 1046|     13|            size_t srcIdx = (*remappingIndices)[i];
 1047|     13|            if (srcIdx >= maxIndexCount) {
  ------------------
  |  Branch (1047:17): [True: 0, False: 13]
  ------------------
 1048|      0|                throw DeadlyImportError("GLTF: index*stride ", (srcIdx * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1049|      0|            }
 1050|     13|            memcpy(outData + i, data + srcIdx * stride, elemSize);
 1051|     13|        }
 1052|      6|    } else { // non-indexed cases
 1053|      4|        if (usedCount * stride > maxSize) {
  ------------------
  |  Branch (1053:13): [True: 0, False: 4]
  ------------------
 1054|      0|            throw DeadlyImportError("GLTF: count*stride ", (usedCount * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1055|      0|        }
 1056|      4|        if (stride == elemSize && targetElemSize == elemSize) {
  ------------------
  |  Branch (1056:13): [True: 4, False: 0]
  |  Branch (1056:35): [True: 3, False: 1]
  ------------------
 1057|      3|            memcpy(outData, data, totalSize);
 1058|      3|        } else {
 1059|      5|            for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1059:32): [True: 4, False: 1]
  ------------------
 1060|      4|                memcpy(outData + i, data + i * stride, elemSize);
 1061|      4|            }
 1062|      1|        }
 1063|      4|    }
 1064|     10|    return usedCount;
 1065|     10|}
_ZN5glTF28Accessor11ExtractDataIA16_fEEmRPT_PKNSt3__16vectorIjNS6_9allocatorIjEEEE:
 1021|    273|size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remappingIndices) {
 1022|    273|    uint8_t *data = GetPointer();
 1023|    273|    if (!data) {
  ------------------
  |  Branch (1023:9): [True: 6, False: 267]
  ------------------
 1024|      6|        throw DeadlyImportError("GLTF2: data is null when extracting data from ", getContextForErrorMessages(id, name));
 1025|      6|    }
 1026|       |
 1027|    267|    const size_t usedCount = (remappingIndices != nullptr) ? remappingIndices->size() : count;
  ------------------
  |  Branch (1027:30): [True: 0, False: 267]
  ------------------
 1028|    267|    const size_t elemSize = GetElementSize();
 1029|    267|    const size_t totalSize = elemSize * usedCount;
 1030|       |
 1031|    267|    const size_t stride = GetStride();
 1032|       |
 1033|    267|    const size_t targetElemSize = sizeof(T);
 1034|       |
 1035|    267|    if (elemSize > targetElemSize) {
  ------------------
  |  Branch (1035:9): [True: 0, False: 267]
  ------------------
 1036|      0|        throw DeadlyImportError("GLTF: elemSize ", elemSize, " > targetElemSize ", targetElemSize, " in ", getContextForErrorMessages(id, name));
 1037|      0|    }
 1038|       |
 1039|    267|    const size_t maxSize = GetMaxByteSize();
 1040|       |
 1041|    267|    outData = new T[usedCount];
 1042|       |
 1043|    267|    if (remappingIndices != nullptr) {
  ------------------
  |  Branch (1043:9): [True: 0, False: 267]
  ------------------
 1044|      0|        const unsigned int maxIndexCount = static_cast<unsigned int>(maxSize / stride);
 1045|      0|        for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1045:28): [True: 0, False: 0]
  ------------------
 1046|      0|            size_t srcIdx = (*remappingIndices)[i];
 1047|      0|            if (srcIdx >= maxIndexCount) {
  ------------------
  |  Branch (1047:17): [True: 0, False: 0]
  ------------------
 1048|      0|                throw DeadlyImportError("GLTF: index*stride ", (srcIdx * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1049|      0|            }
 1050|      0|            memcpy(outData + i, data + srcIdx * stride, elemSize);
 1051|      0|        }
 1052|    267|    } else { // non-indexed cases
 1053|    267|        if (usedCount * stride > maxSize) {
  ------------------
  |  Branch (1053:13): [True: 0, False: 267]
  ------------------
 1054|      0|            throw DeadlyImportError("GLTF: count*stride ", (usedCount * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
 1055|      0|        }
 1056|    267|        if (stride == elemSize && targetElemSize == elemSize) {
  ------------------
  |  Branch (1056:13): [True: 267, False: 0]
  |  Branch (1056:35): [True: 214, False: 53]
  ------------------
 1057|    214|            memcpy(outData, data, totalSize);
 1058|    214|        } else {
 1059|    593|            for (size_t i = 0; i < usedCount; ++i) {
  ------------------
  |  Branch (1059:32): [True: 540, False: 53]
  ------------------
 1060|    540|                memcpy(outData + i, data + i * stride, elemSize);
 1061|    540|            }
 1062|     53|        }
 1063|    267|    }
 1064|    267|    return usedCount;
 1065|    267|}

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

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

_ZN10glTFCommon10ReadHelperIbE4ReadERN9rapidjson12GenericValueINS2_4UTF8IcEENS2_19MemoryPoolAllocatorINS2_12CrtAllocatorEEEEERb:
  289|    924|    static bool Read(Value &val, bool &out) {
  290|    924|        return val.IsBool() ? out = val.GetBool(), true : false;
  ------------------
  |  Branch (290:16): [True: 906, False: 18]
  ------------------
  291|    924|    }
_ZN10glTFCommon10ReadHelperIfE4ReadERN9rapidjson12GenericValueINS2_4UTF8IcEENS2_19MemoryPoolAllocatorINS2_12CrtAllocatorEEEEERf:
  296|  1.32k|    static bool Read(Value &val, float &out) {
  297|  1.32k|        return val.IsNumber() ? out = static_cast<float>(val.GetDouble()), true : false;
  ------------------
  |  Branch (297:16): [True: 1.30k, False: 19]
  ------------------
  298|  1.32k|    }
_ZN10glTFCommon10ReadHelperIPKcE4ReadERN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEERS2_:
  315|  6.79k|    static bool Read(Value &val, const char *&out) {
  316|  6.79k|        return val.IsString() ? (out = val.GetString(), true) : false;
  ------------------
  |  Branch (316:16): [True: 6.79k, False: 1]
  ------------------
  317|  6.79k|    }
_ZN10glTFCommon10ReadHelperINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEE4ReadERN9rapidjson12GenericValueINS9_4UTF8IcEENS9_19MemoryPoolAllocatorINS9_12CrtAllocatorEEEEERS7_:
  322|  26.7k|    static bool Read(Value &val, std::string &out) {
  323|  26.7k|        return val.IsString() ? (out = std::string(val.GetString(), val.GetStringLength()), true) : false;
  ------------------
  |  Branch (323:16): [True: 26.7k, False: 22]
  ------------------
  324|  26.7k|    }
_ZN10glTFCommon10ReadHelperImE4ReadERN9rapidjson12GenericValueINS2_4UTF8IcEENS2_19MemoryPoolAllocatorINS2_12CrtAllocatorEEEEERm:
  336|  19.0k|    static bool Read(Value &val, uint64_t &out) {
  337|  19.0k|        return val.IsUint64() ? out = val.GetUint64(), true : false;
  ------------------
  |  Branch (337:16): [True: 19.0k, False: 4]
  ------------------
  338|  19.0k|    }
_ZN10glTFCommon9CopyValueERA3_KfR9aiColor4tIfE:
  138|  3.09k|inline void CopyValue(const glTFCommon::vec3 &v, aiColor4D &out) {
  139|  3.09k|    out.r = v[0];
  140|  3.09k|    out.g = v[1];
  141|  3.09k|    out.b = v[2];
  142|  3.09k|    out.a = 1.0;
  143|  3.09k|}
_ZN10glTFCommon9CopyValueERA4_KfR9aiColor4tIfE:
  145|  6.19k|inline void CopyValue(const glTFCommon::vec4 &v, aiColor4D &out) {
  146|  6.19k|    out.r = v[0];
  147|  6.19k|    out.g = v[1];
  148|  6.19k|    out.b = v[2];
  149|  6.19k|    out.a = v[3];
  150|  6.19k|}
_ZN10glTFCommon9CopyValueERA16_KfR12aiMatrix4x4tIfE:
  177|  11.5k|inline void CopyValue(const glTFCommon::mat4 &v, aiMatrix4x4 &o) {
  178|  11.5k|    o.a1 = v[0];
  179|  11.5k|    o.b1 = v[1];
  180|  11.5k|    o.c1 = v[2];
  181|  11.5k|    o.d1 = v[3];
  182|  11.5k|    o.a2 = v[4];
  183|  11.5k|    o.b2 = v[5];
  184|  11.5k|    o.c2 = v[6];
  185|  11.5k|    o.d2 = v[7];
  186|  11.5k|    o.a3 = v[8];
  187|  11.5k|    o.b3 = v[9];
  188|  11.5k|    o.c3 = v[10];
  189|  11.5k|    o.d3 = v[11];
  190|  11.5k|    o.a4 = v[12];
  191|  11.5k|    o.b4 = v[13];
  192|  11.5k|    o.c4 = v[14];
  193|  11.5k|    o.d4 = v[15];
  194|  11.5k|}
_ZN10glTFCommon10FindMemberERN9rapidjson12GenericValueINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEEEEPKc:
  386|  8.08k|inline Value *FindMember(Value &val, const char *id) {
  387|  8.08k|    if (!val.IsObject()) {
  ------------------
  |  Branch (387:9): [True: 0, False: 8.08k]
  ------------------
  388|      0|        return nullptr;
  389|      0|    }
  390|  8.08k|    Value::MemberIterator it = val.FindMember(id);
  391|  8.08k|    return (it != val.MemberEnd()) ? &it->value : nullptr;
  ------------------
  |  Branch (391:12): [True: 1.57k, False: 6.51k]
  ------------------
  392|  8.08k|}
_ZN10glTFCommon19FindStringInContextERN9rapidjson12GenericValueINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEEEEPKcSA_SA_:
  405|  6.32k|inline Value *FindStringInContext(Value &val, const char *memberId, const char *context, const char *extraContext = nullptr) {
  406|  6.32k|    if (!val.IsObject()) {
  ------------------
  |  Branch (406:9): [True: 0, False: 6.32k]
  ------------------
  407|      0|        return nullptr;
  408|      0|    }
  409|  6.32k|    Value::MemberIterator it = val.FindMember(memberId);
  410|  6.32k|    if (it == val.MemberEnd()) {
  ------------------
  |  Branch (410:9): [True: 2.43k, False: 3.89k]
  ------------------
  411|  2.43k|        return nullptr;
  412|  2.43k|    }
  413|  3.89k|    if (!it->value.IsString()) {
  ------------------
  |  Branch (413:9): [True: 25, False: 3.86k]
  ------------------
  414|     25|        throwUnexpectedTypeError("string", memberId, context, extraContext);
  415|     25|    }
  416|  3.89k|    return &it->value;
  417|  6.32k|}
_ZN10glTFCommon17FindUIntInContextERN9rapidjson12GenericValueINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEEEEPKcSA_SA_:
  433|  61.5k|inline Value *FindUIntInContext(Value &val, const char *memberId, const char *context, const char *extraContext = nullptr) {
  434|  61.5k|    if (!val.IsObject()) {
  ------------------
  |  Branch (434:9): [True: 2, False: 61.5k]
  ------------------
  435|      2|        return nullptr;
  436|      2|    }
  437|  61.5k|    Value::MemberIterator it = val.FindMember(memberId);
  438|  61.5k|    if (it == val.MemberEnd()) {
  ------------------
  |  Branch (438:9): [True: 33.5k, False: 27.9k]
  ------------------
  439|  33.5k|        return nullptr;
  440|  33.5k|    }
  441|  27.9k|    if (!it->value.IsUint()) {
  ------------------
  |  Branch (441:9): [True: 27, False: 27.9k]
  ------------------
  442|     27|        throwUnexpectedTypeError("uint", memberId, context, extraContext);
  443|     27|    }
  444|  27.9k|    return &it->value;
  445|  61.5k|}
_ZN10glTFCommon18FindArrayInContextERN9rapidjson12GenericValueINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEEEEPKcSA_SA_:
  447|  68.2k|inline Value *FindArrayInContext(Value &val, const char *memberId, const char *context, const char *extraContext = nullptr) {
  448|  68.2k|    if (!val.IsObject()) {
  ------------------
  |  Branch (448:9): [True: 1, False: 68.2k]
  ------------------
  449|      1|        return nullptr;
  450|      1|    }
  451|  68.2k|    Value::MemberIterator it = val.FindMember(memberId);
  452|  68.2k|    if (it == val.MemberEnd()) {
  ------------------
  |  Branch (452:9): [True: 31.4k, False: 36.7k]
  ------------------
  453|  31.4k|        return nullptr;
  454|  31.4k|    }
  455|  36.7k|    if (!it->value.IsArray()) {
  ------------------
  |  Branch (455:9): [True: 24, False: 36.7k]
  ------------------
  456|     24|        throwUnexpectedTypeError("array", memberId, context, extraContext);
  457|     24|    }
  458|  36.7k|    return &it->value;
  459|  68.2k|}
_ZN10glTFCommon19FindObjectInContextERN9rapidjson12GenericValueINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEEEEPKcSA_SA_:
  461|   100k|inline Value *FindObjectInContext(Value &val, const char * memberId, const char *context, const char *extraContext = nullptr) {
  462|   100k|    if (!val.IsObject()) {
  ------------------
  |  Branch (462:9): [True: 2, False: 100k]
  ------------------
  463|      2|        return nullptr;
  464|      2|    }
  465|   100k|    Value::MemberIterator it = val.FindMember(memberId);
  466|   100k|    if (it == val.MemberEnd()) {
  ------------------
  |  Branch (466:9): [True: 84.8k, False: 15.5k]
  ------------------
  467|  84.8k|        return nullptr;
  468|  84.8k|    }
  469|  15.5k|    if (!it->value.IsObject()) {
  ------------------
  |  Branch (469:9): [True: 40, False: 15.5k]
  ------------------
  470|     40|        ASSIMP_LOG_ERROR("Member \"", memberId, "\" was not of type \"", context, "\" when reading ", extraContext);
  471|     40|        return nullptr;
  472|     40|   }
  473|  15.5k|    return &it->value;
  474|  15.5k|}
_ZN10glTFCommon10FindStringERN9rapidjson15GenericDocumentINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEES5_EEPKc:
  487|    176|inline Value *FindString(Document &doc, const char *memberId) {
  488|    176|    return FindStringInContext(doc, memberId, "the document");
  489|    176|}
_ZN10glTFCommon8FindUIntERN9rapidjson15GenericDocumentINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEES5_EEPKc:
  495|  2.09k|inline Value *FindUInt(Document &doc, const char *memberId) {
  496|  2.09k|    return FindUIntInContext(doc, memberId, "the document");
  497|  2.09k|}
_ZN10glTFCommon9FindArrayERN9rapidjson15GenericDocumentINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEES5_EEPKc:
  499|  10.1k|inline Value *FindArray(Document &val, const char *memberId) {
  500|  10.1k|    return FindArrayInContext(val, memberId, "the document");
  501|  10.1k|}
_ZN10glTFCommon10FindObjectERN9rapidjson15GenericDocumentINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEES5_EEPKc:
  503|  9.53k|inline Value *FindObject(Document &doc, const char *memberId) {
  504|  9.53k|    return FindObjectInContext(doc, memberId, "the document");
  505|  9.53k|}
_ZN10glTFCommon10FindStringERN9rapidjson12GenericValueINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEEEEPKc:
  511|    543|inline Value *FindString(Value &val, const char *id) {
  512|    543|    Value::MemberIterator it = val.FindMember(id);
  513|    543|    return (it != val.MemberEnd() && it->value.IsString()) ? &it->value : nullptr;
  ------------------
  |  Branch (513:13): [True: 507, False: 36]
  |  Branch (513:38): [True: 499, False: 8]
  ------------------
  514|    543|}
_ZN10glTFCommon10FindObjectERN9rapidjson12GenericValueINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEEEEPKc:
  516|  2.83k|inline Value *FindObject(Value &val, const char *id) {
  517|  2.83k|    Value::MemberIterator it = val.FindMember(id);
  518|  2.83k|    return (it != val.MemberEnd() && it->value.IsObject()) ? &it->value : nullptr;
  ------------------
  |  Branch (518:13): [True: 60, False: 2.77k]
  |  Branch (518:38): [True: 0, False: 60]
  ------------------
  519|  2.83k|}
_ZN10glTFCommon10FindNumberERN9rapidjson12GenericValueINS0_4UTF8IcEENS0_19MemoryPoolAllocatorINS0_12CrtAllocatorEEEEEPKc:
  526|     44|inline Value *FindNumber(Value &val, const char *id) {
  527|     44|    Value::MemberIterator it = val.FindMember(id);
  528|     44|    return (it != val.MemberEnd() && it->value.IsNumber()) ? &it->value : nullptr;
  ------------------
  |  Branch (528:13): [True: 8, False: 36]
  |  Branch (528:38): [True: 6, False: 2]
  ------------------
  529|     44|}
_ZN10glTFCommon24throwUnexpectedTypeErrorILi7EEEvRAT__KcPS1_S4_S4_:
  395|     25|inline void throwUnexpectedTypeError(const char (&expectedTypeName)[N], const char *memberId, const char *context, const char *extraContext) {
  396|     25|    std::string fullContext = context;
  397|     25|    if (extraContext && (strlen(extraContext) > 0)) {
  ------------------
  |  Branch (397:9): [True: 1, False: 24]
  |  Branch (397:25): [True: 0, False: 1]
  ------------------
  398|      0|        fullContext = fullContext + " (" + extraContext + ")";
  399|      0|    }
  400|     25|    throw DeadlyImportError("Member \"", memberId, "\" was not of type \"", expectedTypeName, "\" when reading ", fullContext);
  401|     25|}
_ZN10glTFCommon24throwUnexpectedTypeErrorILi5EEEvRAT__KcPS1_S4_S4_:
  395|     27|inline void throwUnexpectedTypeError(const char (&expectedTypeName)[N], const char *memberId, const char *context, const char *extraContext) {
  396|     27|    std::string fullContext = context;
  397|     27|    if (extraContext && (strlen(extraContext) > 0)) {
  ------------------
  |  Branch (397:9): [True: 17, False: 10]
  |  Branch (397:25): [True: 10, False: 7]
  ------------------
  398|     10|        fullContext = fullContext + " (" + extraContext + ")";
  399|     10|    }
  400|     27|    throw DeadlyImportError("Member \"", memberId, "\" was not of type \"", expectedTypeName, "\" when reading ", fullContext);
  401|     27|}
_ZN10glTFCommon24throwUnexpectedTypeErrorILi6EEEvRAT__KcPS1_S4_S4_:
  395|     24|inline void throwUnexpectedTypeError(const char (&expectedTypeName)[N], const char *memberId, const char *context, const char *extraContext) {
  396|     24|    std::string fullContext = context;
  397|     24|    if (extraContext && (strlen(extraContext) > 0)) {
  ------------------
  |  Branch (397:9): [True: 9, False: 15]
  |  Branch (397:25): [True: 6, False: 3]
  ------------------
  398|      6|        fullContext = fullContext + " (" + extraContext + ")";
  399|      6|    }
  400|     24|    throw DeadlyImportError("Member \"", memberId, "\" was not of type \"", expectedTypeName, "\" when reading ", fullContext);
  401|     24|}
_ZN10glTFCommon10ReadHelperINS_8NullableINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEEE4ReadERN9rapidjson12GenericValueINSB_4UTF8IcEENSB_19MemoryPoolAllocatorINSB_12CrtAllocatorEEEEERS9_:
  329|  8.18k|    static bool Read(Value &val, Nullable<T> &out) {
  330|  8.18k|        return out.isPresent = ReadHelper<T>::Read(val, out.value);
  331|  8.18k|    }
_ZNK10glTFCommon3RefIN5glTF26BufferEEcvbEv:
  269|  16.9k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 12.6k, False: 4.23k]
  |  Branch (269:57): [True: 12.6k, False: 0]
  ------------------
_ZN10glTFCommon10ReadHelperIjE4ReadERN9rapidjson12GenericValueINS2_4UTF8IcEENS2_19MemoryPoolAllocatorINS2_12CrtAllocatorEEEEERj:
  282|  1.52k|    static bool Read(Value &val, T &out) {
  283|  1.52k|        return val.IsInt() ? out = static_cast<T>(val.GetInt()), true : false;
  ------------------
  |  Branch (283:16): [True: 1.52k, False: 1]
  ------------------
  284|  1.52k|    }
_ZN10glTFCommon3RefIN5glTF26BufferEEptEv:
  271|  31.6k|    T *operator->() { return (*vector)[index]; }
_ZN10glTFCommon3RefIN5glTF210BufferViewEEptEv:
  271|   121k|    T *operator->() { return (*vector)[index]; }
_ZN10glTFCommon10ReadHelperIN5glTF213ComponentTypeEE4ReadERN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEERS2_:
  282|  5.56k|    static bool Read(Value &val, T &out) {
  283|  5.56k|        return val.IsInt() ? out = static_cast<T>(val.GetInt()), true : false;
  ------------------
  |  Branch (283:16): [True: 5.54k, False: 14]
  ------------------
  284|  5.56k|    }
_ZNK10glTFCommon3RefIN5glTF210BufferViewEEcvbEv:
  269|  56.1k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 55.9k, False: 206]
  |  Branch (269:57): [True: 55.9k, False: 0]
  ------------------
_ZN10glTFCommon10ReadHelperIN5glTF216SamplerMagFilterEE4ReadERN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEERS2_:
  282|      7|    static bool Read(Value &val, T &out) {
  283|      7|        return val.IsInt() ? out = static_cast<T>(val.GetInt()), true : false;
  ------------------
  |  Branch (283:16): [True: 6, False: 1]
  ------------------
  284|      7|    }
_ZN10glTFCommon10ReadHelperIN5glTF216SamplerMinFilterEE4ReadERN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEERS2_:
  282|     51|    static bool Read(Value &val, T &out) {
  283|     51|        return val.IsInt() ? out = static_cast<T>(val.GetInt()), true : false;
  ------------------
  |  Branch (283:16): [True: 50, False: 1]
  ------------------
  284|     51|    }
_ZN10glTFCommon10ReadHelperIN5glTF211SamplerWrapEE4ReadERN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEERS2_:
  282|    111|    static bool Read(Value &val, T &out) {
  283|    111|        return val.IsInt() ? out = static_cast<T>(val.GetInt()), true : false;
  ------------------
  |  Branch (283:16): [True: 108, False: 3]
  ------------------
  284|    111|    }
_ZN10glTFCommon10ReadHelperIA4_fE4ReadERN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEERS1_:
  303|    878|    static bool Read(Value &val, float (&out)[N]) {
  304|    878|        if (!val.IsArray() || val.Size() != N) return false;
  ------------------
  |  Branch (304:13): [True: 1, False: 877]
  |  Branch (304:31): [True: 4, False: 873]
  ------------------
  305|  4.36k|        for (unsigned int i = 0; i < N; ++i) {
  ------------------
  |  Branch (305:34): [True: 3.49k, False: 873]
  ------------------
  306|  3.49k|            if (val[i].IsNumber())
  ------------------
  |  Branch (306:17): [True: 3.49k, False: 0]
  ------------------
  307|  3.49k|                out[i] = static_cast<float>(val[i].GetDouble());
  308|  3.49k|        }
  309|    873|        return true;
  310|    878|    }
_ZN10glTFCommon10ReadHelperIA3_fE4ReadERN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEERS1_:
  303|    881|    static bool Read(Value &val, float (&out)[N]) {
  304|    881|        if (!val.IsArray() || val.Size() != N) return false;
  ------------------
  |  Branch (304:13): [True: 1, False: 880]
  |  Branch (304:31): [True: 9, False: 871]
  ------------------
  305|  3.48k|        for (unsigned int i = 0; i < N; ++i) {
  ------------------
  |  Branch (305:34): [True: 2.61k, False: 871]
  ------------------
  306|  2.61k|            if (val[i].IsNumber())
  ------------------
  |  Branch (306:17): [True: 2.61k, False: 0]
  ------------------
  307|  2.61k|                out[i] = static_cast<float>(val[i].GetDouble());
  308|  2.61k|        }
  309|    871|        return true;
  310|    881|    }
_ZN10glTFCommon10ReadHelperIN5glTF213PrimitiveModeEE4ReadERN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEERS2_:
  282|  1.64k|    static bool Read(Value &val, T &out) {
  283|  1.64k|        return val.IsInt() ? out = static_cast<T>(val.GetInt()), true : false;
  ------------------
  |  Branch (283:16): [True: 1.64k, False: 1]
  ------------------
  284|  1.64k|    }
_ZNK10glTFCommon3RefIN5glTF24NodeEEcvbEv:
  269|  14.2k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 14.2k, False: 0]
  |  Branch (269:57): [True: 14.2k, False: 0]
  ------------------
_ZN10glTFCommon10ReadHelperINS_8NullableIA16_fEEE4ReadERN9rapidjson12GenericValueINS5_4UTF8IcEENS5_19MemoryPoolAllocatorINS5_12CrtAllocatorEEEEERS3_:
  329|  9.62k|    static bool Read(Value &val, Nullable<T> &out) {
  330|  9.62k|        return out.isPresent = ReadHelper<T>::Read(val, out.value);
  331|  9.62k|    }
_ZN10glTFCommon10ReadHelperIA16_fE4ReadERN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEERS1_:
  303|  9.62k|    static bool Read(Value &val, float (&out)[N]) {
  304|  9.62k|        if (!val.IsArray() || val.Size() != N) return false;
  ------------------
  |  Branch (304:13): [True: 0, False: 9.62k]
  |  Branch (304:31): [True: 87, False: 9.54k]
  ------------------
  305|   162k|        for (unsigned int i = 0; i < N; ++i) {
  ------------------
  |  Branch (305:34): [True: 152k, False: 9.54k]
  ------------------
  306|   152k|            if (val[i].IsNumber())
  ------------------
  |  Branch (306:17): [True: 152k, False: 3]
  ------------------
  307|   152k|                out[i] = static_cast<float>(val[i].GetDouble());
  308|   152k|        }
  309|  9.54k|        return true;
  310|  9.62k|    }
_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.61k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 1.61k, False: 0]
  |  Branch (269:57): [True: 1.61k, False: 0]
  ------------------
_ZNK10glTFCommon3RefIN5glTF26CameraEEcvbEv:
  269|  7.98k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 0, False: 7.98k]
  |  Branch (269:57): [True: 0, False: 0]
  ------------------
_ZNK10glTFCommon3RefIN5glTF25LightEEcvbEv:
  269|  7.98k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 0, False: 7.98k]
  |  Branch (269:57): [True: 0, False: 0]
  ------------------
_ZN10glTFCommon3RefIN5glTF25SceneEEptEv:
  271|  7.62k|    T *operator->() { return (*vector)[index]; }
_ZN10glTFCommon3RefIN4glTF6BufferEEC2Ev:
  261|  4.31k|            vector(nullptr),
  262|  4.31k|            index(0) {}
_ZN10glTFCommon3RefIN4glTF5SceneEEC2Ev:
  261|  4.31k|            vector(nullptr),
  262|  4.31k|            index(0) {}
_ZN10glTFCommon3RefIN4glTF6BufferEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|  2.32k|            vector(&vec),
  265|  2.32k|            index(idx) {}
glTFImporter.cpp:_ZN10glTFCommonL10ReadMemberINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEEbRN9rapidjson12GenericValueINS8_4UTF8IcEENS8_19MemoryPoolAllocatorINS8_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: 186, False: 900]
  ------------------
  375|    186|        return ReadHelper<T>::Read(it->value, out);
  376|    186|    }
  377|    900|    return false;
  378|  1.08k|}
glTFImporter.cpp:_ZN10glTFCommonL15MemberOrDefaultIbEET_RN9rapidjson12GenericValueINS2_4UTF8IcEENS2_19MemoryPoolAllocatorINS2_12CrtAllocatorEEEEEPKcS1_:
  381|    543|inline static T MemberOrDefault(Value &obj, const char *id, T defaultValue) {
  382|    543|    T out;
  383|    543|    return ReadMember(obj, id, out) ? out : defaultValue;
  ------------------
  |  Branch (383:12): [True: 0, False: 543]
  ------------------
  384|    543|}
glTFImporter.cpp:_ZN10glTFCommonL10ReadMemberIbEEbRN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEEPKcRT_:
  369|    543|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|    543|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 543]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|    543|    Value::MemberIterator it = obj.FindMember(id);
  374|    543|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 17, False: 526]
  ------------------
  375|     17|        return ReadHelper<T>::Read(it->value, out);
  376|     17|    }
  377|    526|    return false;
  378|    543|}
_ZN10glTFCommon8NullableIA16_fEC2Ev:
  246|  12.2k|            isPresent(false) {}
_ZN10glTFCommon8NullableIA3_fEC2Ev:
  246|  23.7k|            isPresent(false) {}
_ZN10glTFCommon8NullableIA4_fEC2Ev:
  246|  11.8k|            isPresent(false) {}
_ZN10glTFCommon3RefIN4glTF6BufferEEptEv:
  271|  2.32k|    T *operator->() { return (*vector)[index]; }
_ZNK10glTFCommon3RefIN4glTF5SceneEEcvbEv:
  269|     80|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 0, False: 80]
  |  Branch (269:57): [True: 0, False: 0]
  ------------------
_ZNK10glTFCommon3RefIN5glTF27TextureEEcvbEv:
  269|  30.9k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 112, False: 30.8k]
  |  Branch (269:57): [True: 112, False: 0]
  ------------------
_ZN10glTFCommon3RefIN5glTF27TextureEEptEv:
  271|    490|    T *operator->() { return (*vector)[index]; }
_ZNK10glTFCommon3RefIN5glTF25ImageEEcvbEv:
  269|    112|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 96, False: 16]
  |  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|    624|    T *operator->() { return (*vector)[index]; }
_ZN10glTFCommon3RefIN5glTF25SceneEEC2Ev:
  261|  6.32k|            vector(nullptr),
  262|  6.32k|            index(0) {}
_ZN10glTFCommon3RefIN5glTF26BufferEEC2Ev:
  261|  13.0k|            vector(nullptr),
  262|  13.0k|            index(0) {}
_ZN10glTFCommon8NullableINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEC2Ev:
  246|  72.8k|            isPresent(false) {}
_ZN10glTFCommon8NullableIdEC2Ev:
  246|  72.8k|            isPresent(false) {}
_ZN10glTFCommon8NullableImEC2Ev:
  246|  72.8k|            isPresent(false) {}
_ZN10glTFCommon8NullableIlEC2Ev:
  246|  72.8k|            isPresent(false) {}
_ZN10glTFCommon8NullableIbEC2Ev:
  246|  72.8k|            isPresent(false) {}
_ZN10glTFCommon8NullableINSt3__16vectorIN5glTF215CustomExtensionENS1_9allocatorIS4_EEEEEC2Ev:
  246|  72.8k|            isPresent(false) {}
_ZN10glTFCommon3RefIN5glTF26BufferEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|  10.8k|            vector(&vec),
  265|  10.8k|            index(idx) {}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEEbRN9rapidjson12GenericValueINS8_4UTF8IcEENS8_19MemoryPoolAllocatorINS8_12CrtAllocatorEEEEEPKcRT_:
  369|  41.0k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  41.0k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 41.0k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  41.0k|    Value::MemberIterator it = obj.FindMember(id);
  374|  41.0k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 18.4k, False: 22.6k]
  ------------------
  375|  18.4k|        return ReadHelper<T>::Read(it->value, out);
  376|  18.4k|    }
  377|  22.6k|    return false;
  378|  41.0k|}
_ZN10glTFCommon3RefIN5glTF27TextureEEC2Ev:
  261|  54.9k|            vector(nullptr),
  262|  54.9k|            index(0) {}
_ZN10glTFCommon8NullableIN5glTF221PbrSpecularGlossinessEEC2Ev:
  246|  3.23k|            isPresent(false) {}
_ZN10glTFCommon8NullableIN5glTF216MaterialSpecularEEC2Ev:
  246|  3.23k|            isPresent(false) {}
_ZN10glTFCommon8NullableIN5glTF213MaterialSheenEEC2Ev:
  246|  3.23k|            isPresent(false) {}
_ZN10glTFCommon8NullableIN5glTF217MaterialClearcoatEEC2Ev:
  246|  3.23k|            isPresent(false) {}
_ZN10glTFCommon8NullableIN5glTF220MaterialTransmissionEEC2Ev:
  246|  3.23k|            isPresent(false) {}
_ZN10glTFCommon8NullableIN5glTF214MaterialVolumeEEC2Ev:
  246|  3.23k|            isPresent(false) {}
_ZN10glTFCommon8NullableIN5glTF211MaterialIOREEC2Ev:
  246|  3.23k|            isPresent(false) {}
_ZN10glTFCommon8NullableIN5glTF224MaterialEmissiveStrengthEEC2Ev:
  246|  3.23k|            isPresent(false) {}
_ZN10glTFCommon8NullableIN5glTF218MaterialAnisotropyEEC2Ev:
  246|  3.23k|            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|  8.18k|inline static bool ReadValue(Value &val, T &out) {
  365|  8.18k|    return ReadHelper<T>::Read(val, out);
  366|  8.18k|}
_ZN10glTFCommon3RefIN5glTF25SceneEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|  1.72k|            vector(&vec),
  265|  1.72k|            index(idx) {}
_ZN10glTFCommon3RefIN5glTF24NodeEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|  14.2k|            vector(&vec),
  265|  14.2k|            index(idx) {}
_ZN10glTFCommon3RefIN5glTF26CameraEEC2Ev:
  261|  11.8k|            vector(nullptr),
  262|  11.8k|            index(0) {}
_ZN10glTFCommon3RefIN5glTF25LightEEC2Ev:
  261|  11.8k|            vector(nullptr),
  262|  11.8k|            index(0) {}
_ZN10glTFCommon3RefIN5glTF24SkinEEC2Ev:
  261|  11.8k|            vector(nullptr),
  262|  11.8k|            index(0) {}
_ZN10glTFCommon3RefIN5glTF24NodeEEC2Ev:
  261|  11.8k|            vector(nullptr),
  262|  11.8k|            index(0) {}
glTF2Importer.cpp:_ZN10glTFCommonL9ReadValueINS_8NullableIA16_fEEEEbRN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEERT_:
  364|  9.62k|inline static bool ReadValue(Value &val, T &out) {
  365|  9.62k|    return ReadHelper<T>::Read(val, out);
  366|  9.62k|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberINS_8NullableIA3_fEEEEbRN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEEPKcRT_:
  369|  3.89k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  3.89k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 3.89k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  3.89k|    Value::MemberIterator it = obj.FindMember(id);
  374|  3.89k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 0, False: 3.89k]
  ------------------
  375|      0|        return ReadHelper<T>::Read(it->value, out);
  376|      0|    }
  377|  3.89k|    return false;
  378|  3.89k|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberINS_8NullableIA4_fEEEEbRN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_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: 0, False: 1.94k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  1.94k|    Value::MemberIterator it = obj.FindMember(id);
  374|  1.94k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 1, False: 1.94k]
  ------------------
  375|      1|        return ReadHelper<T>::Read(it->value, out);
  376|      1|    }
  377|  1.94k|    return false;
  378|  1.94k|}
_ZN10glTFCommon3RefIN5glTF24MeshEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|  1.61k|            vector(&vec),
  265|  1.61k|            index(idx) {}
_ZN10glTFCommon3RefIN5glTF28AccessorEEC2Ev:
  261|  8.04k|            vector(nullptr),
  262|  8.04k|            index(0) {}
_ZN10glTFCommon3RefIN5glTF28MaterialEEC2Ev:
  261|  1.77k|            vector(nullptr),
  262|  1.77k|            index(0) {}
glTF2Importer.cpp:_ZN10glTFCommonL15MemberOrDefaultIN5glTF213PrimitiveModeEEET_RN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEEPKcS3_:
  381|  1.77k|inline static T MemberOrDefault(Value &obj, const char *id, T defaultValue) {
  382|  1.77k|    T out;
  383|  1.77k|    return ReadMember(obj, id, out) ? out : defaultValue;
  ------------------
  |  Branch (383:12): [True: 1.64k, False: 138]
  ------------------
  384|  1.77k|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIN5glTF213PrimitiveModeEEEbRN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEEPKcRT_:
  369|  1.77k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  1.77k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 1, False: 1.77k]
  ------------------
  371|      1|        return false;
  372|      1|    }
  373|  1.77k|    Value::MemberIterator it = obj.FindMember(id);
  374|  1.77k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 1.64k, False: 136]
  ------------------
  375|  1.64k|        return ReadHelper<T>::Read(it->value, out);
  376|  1.64k|    }
  377|    136|    return false;
  378|  1.77k|}
_ZN10glTFCommon3RefIN5glTF28AccessorEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|  7.17k|            vector(&vec),
  265|  7.17k|            index(idx) {}
_ZN10glTFCommon3RefIN5glTF210BufferViewEEC2Ev:
  261|  7.17k|            vector(nullptr),
  262|  7.17k|            index(0) {}
_ZN10glTFCommon3RefIN5glTF210BufferViewEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|  6.98k|            vector(&vec),
  265|  6.98k|            index(idx) {}
glTF2Importer.cpp:_ZN10glTFCommonL15MemberOrDefaultIjEET_RN9rapidjson12GenericValueINS2_4UTF8IcEENS2_19MemoryPoolAllocatorINS2_12CrtAllocatorEEEEEPKcS1_:
  381|  6.67k|inline static T MemberOrDefault(Value &obj, const char *id, T defaultValue) {
  382|  6.67k|    T out;
  383|  6.67k|    return ReadMember(obj, id, out) ? out : defaultValue;
  ------------------
  |  Branch (383:12): [True: 1.52k, False: 5.14k]
  ------------------
  384|  6.67k|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIjEEbRN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEEPKcRT_:
  369|  6.67k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  6.67k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 6.67k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  6.67k|    Value::MemberIterator it = obj.FindMember(id);
  374|  6.67k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 1.52k, False: 5.14k]
  ------------------
  375|  1.52k|        return ReadHelper<T>::Read(it->value, out);
  376|  1.52k|    }
  377|  5.14k|    return false;
  378|  6.67k|}
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: 19.0k, False: 1.32k]
  ------------------
  384|  20.4k|}
glTF2Importer.cpp:_ZN10glTFCommonL15MemberOrDefaultIN5glTF213ComponentTypeEEET_RN9rapidjson12GenericValueINS4_4UTF8IcEENS4_19MemoryPoolAllocatorINS4_12CrtAllocatorEEEEEPKcS3_:
  381|  7.06k|inline static T MemberOrDefault(Value &obj, const char *id, T defaultValue) {
  382|  7.06k|    T out;
  383|  7.06k|    return ReadMember(obj, id, out) ? out : defaultValue;
  ------------------
  |  Branch (383:12): [True: 5.54k, False: 1.51k]
  ------------------
  384|  7.06k|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIN5glTF213ComponentTypeEEEbRN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEEPKcRT_:
  369|  7.06k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  7.06k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 7.06k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  7.06k|    Value::MemberIterator it = obj.FindMember(id);
  374|  7.06k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 5.56k, False: 1.50k]
  ------------------
  375|  5.56k|        return ReadHelper<T>::Read(it->value, out);
  376|  5.56k|    }
  377|  1.50k|    return false;
  378|  7.06k|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIPKcEEbRN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEES2_RT_:
  369|  7.05k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  7.05k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 7.05k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  7.05k|    Value::MemberIterator it = obj.FindMember(id);
  374|  7.05k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 6.79k, False: 257]
  ------------------
  375|  6.79k|        return ReadHelper<T>::Read(it->value, out);
  376|  6.79k|    }
  377|    257|    return false;
  378|  7.05k|}
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: 19.0k, False: 1.32k]
  ------------------
  375|  19.0k|        return ReadHelper<T>::Read(it->value, out);
  376|  19.0k|    }
  377|  1.32k|    return false;
  378|  20.4k|}
_ZN10glTFCommon3RefIN5glTF28MaterialEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|  1.41k|            vector(&vec),
  265|  1.41k|            index(idx) {}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIA4_fEEbRN9rapidjson12GenericValueINS2_4UTF8IcEENS2_19MemoryPoolAllocatorINS2_12CrtAllocatorEEEEEPKcRT_:
  369|  1.03k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  1.03k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 1.03k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  1.03k|    Value::MemberIterator it = obj.FindMember(id);
  374|  1.03k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 877, False: 155]
  ------------------
  375|    877|        return ReadHelper<T>::Read(it->value, out);
  376|    877|    }
  377|    155|    return false;
  378|  1.03k|}
_ZN10glTFCommon3RefIN5glTF27TextureEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|     63|            vector(&vec),
  265|     63|            index(idx) {}
_ZN10glTFCommon3RefIN5glTF27SamplerEEC2Ev:
  261|     71|            vector(nullptr),
  262|     71|            index(0) {}
_ZN10glTFCommon3RefIN5glTF25ImageEEC2Ev:
  261|     71|            vector(nullptr),
  262|     71|            index(0) {}
_ZN10glTFCommon3RefIN5glTF25ImageEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|     57|            vector(&vec),
  265|     57|            index(idx) {}
_ZN10glTFCommon3RefIN5glTF27SamplerEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|     58|            vector(&vec),
  265|     58|            index(idx) {}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIN5glTF216SamplerMagFilterEEEbRN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEEPKcRT_:
  369|     58|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|     58|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 58]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|     58|    Value::MemberIterator it = obj.FindMember(id);
  374|     58|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 7, False: 51]
  ------------------
  375|      7|        return ReadHelper<T>::Read(it->value, out);
  376|      7|    }
  377|     51|    return false;
  378|     58|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIN5glTF216SamplerMinFilterEEEbRN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEEPKcRT_:
  369|     58|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|     58|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 58]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|     58|    Value::MemberIterator it = obj.FindMember(id);
  374|     58|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 51, False: 7]
  ------------------
  375|     51|        return ReadHelper<T>::Read(it->value, out);
  376|     51|    }
  377|      7|    return false;
  378|     58|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIN5glTF211SamplerWrapEEEbRN9rapidjson12GenericValueINS3_4UTF8IcEENS3_19MemoryPoolAllocatorINS3_12CrtAllocatorEEEEEPKcRT_:
  369|    116|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|    116|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 116]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|    116|    Value::MemberIterator it = obj.FindMember(id);
  374|    116|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 111, False: 5]
  ------------------
  375|    111|        return ReadHelper<T>::Read(it->value, out);
  376|    111|    }
  377|      5|    return false;
  378|    116|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIfEEbRN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEEPKcRT_:
  369|  3.45k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  3.45k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 3.45k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  3.45k|    Value::MemberIterator it = obj.FindMember(id);
  374|  3.45k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 1.32k, False: 2.13k]
  ------------------
  375|  1.32k|        return ReadHelper<T>::Read(it->value, out);
  376|  1.32k|    }
  377|  2.13k|    return false;
  378|  3.45k|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIA3_fEEbRN9rapidjson12GenericValueINS2_4UTF8IcEENS2_19MemoryPoolAllocatorINS2_12CrtAllocatorEEEEEPKcRT_:
  369|  1.41k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  1.41k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 1.41k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  1.41k|    Value::MemberIterator it = obj.FindMember(id);
  374|  1.41k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 881, False: 534]
  ------------------
  375|    881|        return ReadHelper<T>::Read(it->value, out);
  376|    881|    }
  377|    534|    return false;
  378|  1.41k|}
glTF2Importer.cpp:_ZN10glTFCommonL10ReadMemberIbEEbRN9rapidjson12GenericValueINS1_4UTF8IcEENS1_19MemoryPoolAllocatorINS1_12CrtAllocatorEEEEEPKcRT_:
  369|  1.41k|inline static bool ReadMember(Value &obj, const char *id, T &out) {
  370|  1.41k|    if (!obj.IsObject()) {
  ------------------
  |  Branch (370:9): [True: 0, False: 1.41k]
  ------------------
  371|      0|        return false;
  372|      0|    }
  373|  1.41k|    Value::MemberIterator it = obj.FindMember(id);
  374|  1.41k|    if (it != obj.MemberEnd()) {
  ------------------
  |  Branch (374:9): [True: 907, False: 508]
  ------------------
  375|    907|        return ReadHelper<T>::Read(it->value, out);
  376|    907|    }
  377|    508|    return false;
  378|  1.41k|}
_ZN10glTFCommon3RefIN5glTF24SkinEEC2ERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEEj:
  264|    718|            vector(&vec),
  265|    718|            index(idx) {}
_ZN10glTFCommon3RefIN5glTF24NodeEEptEv:
  271|  5.14k|    T *operator->() { return (*vector)[index]; }
_ZN10glTFCommon3RefIN5glTF28AccessorEEptEv:
  271|  12.1k|    T *operator->() { return (*vector)[index]; }
_ZNK10glTFCommon3RefIN5glTF28MaterialEEcvbEv:
  269|  1.28k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 1.05k, False: 232]
  |  Branch (269:57): [True: 1.05k, False: 0]
  ------------------
_ZNK10glTFCommon3RefIN5glTF28AccessorEEcvbEv:
  269|  6.12k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 5.50k, False: 613]
  |  Branch (269:57): [True: 5.50k, False: 0]
  ------------------
_ZN10glTFCommon3RefIN5glTF24MeshEEptEv:
  271|    310|    T *operator->() { return (*vector)[index]; }
_ZNK10glTFCommon3RefIN5glTF24SkinEEcvbEv:
  269|  1.39k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 326, False: 1.06k]
  |  Branch (269:57): [True: 324, False: 2]
  ------------------
_ZN10glTFCommon3RefIN5glTF24SkinEEptEv:
  271|  3.15k|    T *operator->() { return (*vector)[index]; }
_ZNK10glTFCommon3RefIN5glTF25SceneEEcvbEv:
  269|  4.71k|    operator bool() const { return vector != nullptr && index < vector->size(); }
  ------------------
  |  Branch (269:36): [True: 4.51k, False: 202]
  |  Branch (269:57): [True: 4.51k, False: 0]
  ------------------
_ZNK10glTFCommon3RefIN5glTF28MaterialEE8GetIndexEv:
  267|  1.05k|    inline unsigned int GetIndex() const { return index; }
_ZN10glTFCommon3RefIN5glTF24NodeEEdeEv:
  273|  10.6k|    T &operator*() { return *((*vector)[index]); }
_ZNK10glTFCommon3RefIN5glTF24MeshEE8GetIndexEv:
  267|  1.39k|    inline unsigned int GetIndex() const { return index; }

_ZN6Assimp12BaseImporterC2Ev:
   92|   155k|        : m_progress() {
   93|       |    // empty
   94|   155k|}
_ZN6Assimp12BaseImporter19UpdateImporterScaleEPNS_8ImporterE:
   96|  1.46k|void BaseImporter::UpdateImporterScale(Importer *pImp) {
   97|  1.46k|    ai_assert(pImp != nullptr);
   98|  1.46k|    ai_assert(importerScale != 0.0);
   99|  1.46k|    ai_assert(fileScale != 0.0);
  100|       |
  101|  1.46k|    double activeScale = importerScale * fileScale;
  102|       |
  103|       |    // Set active scaling
  104|  1.46k|    pImp->SetPropertyFloat(AI_CONFIG_APP_SCALE_KEY, static_cast<float>(activeScale));
  105|       |
  106|       |    ASSIMP_LOG_DEBUG("UpdateImporterScale scale set: ", activeScale);
  107|  1.46k|}
_ZN6Assimp12BaseImporter8ReadFileEPNS_8ImporterERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPNS_8IOSystemE:
  111|  2.25k|aiScene *BaseImporter::ReadFile(Importer *pImp, const std::string &pFile, IOSystem *pIOHandler) {
  112|       |
  113|  2.25k|    m_progress = pImp->GetProgressHandler();
  114|  2.25k|    if (nullptr == m_progress) {
  ------------------
  |  Branch (114:9): [True: 0, False: 2.25k]
  ------------------
  115|      0|        return nullptr;
  116|      0|    }
  117|       |
  118|  2.25k|    ai_assert(m_progress);
  119|       |
  120|       |    // Gather configuration properties for this run
  121|  2.25k|    SetupProperties(pImp);
  122|       |
  123|       |    // Construct a file system filter to improve our success ratio at reading external files
  124|  2.25k|    FileSystemFilter filter(pFile, pIOHandler);
  125|       |
  126|       |    // create a scene object to hold the data
  127|  2.25k|    std::unique_ptr<aiScene> sc(new aiScene());
  128|       |
  129|       |    // dispatch importing
  130|  2.25k|    try {
  131|  2.25k|        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.25k|        UpdateImporterScale(pImp);
  136|       |
  137|  2.25k|    } catch( const std::exception &err ) {
  138|       |        // extract error description
  139|    789|        m_ErrorText = err.what();
  140|    789|        ASSIMP_LOG_ERROR(err.what());
  141|    789|        m_Exception = std::current_exception();
  142|    789|        return nullptr;
  143|    789|    }
  144|       |
  145|       |    // return what we gathered from the import.
  146|  1.46k|    return sc.release();
  147|  2.25k|}
_ZN6Assimp12BaseImporter15SetupPropertiesEPKNS_8ImporterE:
  150|     80|void BaseImporter::SetupProperties(const Importer *) {
  151|       |    // the default implementation does nothing
  152|     80|}
_ZN6Assimp12BaseImporter16GetExtensionListERNSt3__13setINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_4lessIS8_EENS6_IS8_EEEE:
  155|  6.48k|void BaseImporter::GetExtensionList(std::set<std::string> &extensions) {
  156|  6.48k|    const aiImporterDesc *desc = GetInfo();
  157|  6.48k|    ai_assert(desc != nullptr);
  158|       |
  159|  6.48k|    const char *ext = desc->mFileExtensions;
  160|  6.48k|    ai_assert(ext != nullptr);
  161|       |
  162|  6.48k|    const char *last = ext;
  163|  71.3k|    do {
  164|  71.3k|        if (!*ext || *ext == ' ') {
  ------------------
  |  Branch (164:13): [True: 6.48k, False: 64.8k]
  |  Branch (164:22): [True: 9.72k, False: 55.1k]
  ------------------
  165|  16.2k|            extensions.insert(std::string(last, ext - last));
  166|  16.2k|            ai_assert(ext - last > 0);
  167|  16.2k|            last = ext;
  168|  25.9k|            while (*last == ' ') {
  ------------------
  |  Branch (168:20): [True: 9.72k, False: 16.2k]
  ------------------
  169|  9.72k|                ++last;
  170|  9.72k|            }
  171|  16.2k|        }
  172|  71.3k|    } while (*ext++);
  ------------------
  |  Branch (172:14): [True: 64.8k, False: 6.48k]
  ------------------
  173|  6.48k|}
_ZN6Assimp12BaseImporter12HasExtensionERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKNS1_3setIS7_NS1_4lessIS7_EENS5_IS7_EEEE:
  265|  6.48k|/*static*/ bool BaseImporter::HasExtension(const std::string &pFile, const std::set<std::string> &extensions) {
  266|  6.48k|    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.48k|    for (const std::string& ext : extensions) {
  ------------------
  |  Branch (271:33): [True: 6.48k, False: 0]
  ------------------
  272|       |        // Yay for C++<20 not having std::string::ends_with()
  273|  6.48k|        const std::string dotExt = "." + ext;
  274|  6.48k|        if (dotExt.length() > file.length()) continue;
  ------------------
  |  Branch (274:13): [True: 0, False: 6.48k]
  ------------------
  275|       |        // Possible optimization: Fetch the lowercase filename!
  276|  6.48k|        if (0 == ASSIMP_stricmp(file.c_str() + file.length() - dotExt.length(), dotExt.c_str())) {
  ------------------
  |  Branch (276:13): [True: 6.48k, False: 0]
  ------------------
  277|  6.48k|            return true;
  278|  6.48k|        }
  279|  6.48k|    }
  280|      0|    return false;
  281|  6.48k|}
_ZN6Assimp12BaseImporter12GetExtensionERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  285|  4.15k|std::string BaseImporter::GetExtension(const std::string &pFile) {
  286|  4.15k|    const std::string file = StripVersionHash(pFile);
  287|  4.15k|    std::string::size_type pos = file.find_last_of('.');
  288|       |
  289|       |    // no file extension at all
  290|  4.15k|    if (pos == std::string::npos) {
  ------------------
  |  Branch (290:9): [True: 0, False: 4.15k]
  ------------------
  291|      0|        return std::string();
  292|      0|    }
  293|       |
  294|       |    // thanks to Andy Maloney for the hint
  295|  4.15k|    std::string ret = file.substr(pos + 1);
  296|  4.15k|    ret = ai_tolower(ret);
  297|       |
  298|  4.15k|    return ret;
  299|  4.15k|}
_ZN6Assimp12BaseImporter15CheckMagicTokenEPNS_8IOSystemERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPKvmjj:
  305|  10.6k|        const void *_magic, std::size_t num, unsigned int offset, unsigned int size) {
  306|  10.6k|    ai_assert(size <= 16);
  307|  10.6k|    ai_assert(_magic);
  308|       |
  309|  10.6k|    if (!pIOHandler) {
  ------------------
  |  Branch (309:9): [True: 0, False: 10.6k]
  ------------------
  310|      0|        return false;
  311|      0|    }
  312|  10.6k|    const char *magic = reinterpret_cast<const char *>(_magic);
  313|  10.6k|    std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile));
  314|  10.6k|    if (pStream) {
  ------------------
  |  Branch (314:9): [True: 10.6k, False: 0]
  ------------------
  315|       |
  316|       |        // skip to offset
  317|  10.6k|        pStream->Seek(offset, aiOrigin_SET);
  318|       |
  319|       |        // read 'size' characters from the file
  320|  10.6k|        union {
  321|  10.6k|            char data[16];
  322|  10.6k|            uint16_t data_u16[8];
  323|  10.6k|            uint32_t data_u32[4];
  324|  10.6k|        };
  325|  10.6k|        if (size != pStream->Read(data, 1, size)) {
  ------------------
  |  Branch (325:13): [True: 0, False: 10.6k]
  ------------------
  326|      0|            return false;
  327|      0|        }
  328|       |
  329|  14.7k|        for (unsigned int i = 0; i < num; ++i) {
  ------------------
  |  Branch (329:34): [True: 10.6k, False: 4.09k]
  ------------------
  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|  10.6k|            if (2 == size) {
  ------------------
  |  Branch (333:17): [True: 0, False: 10.6k]
  ------------------
  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|  10.6k|            } else if (4 == size) {
  ------------------
  |  Branch (339:24): [True: 10.6k, False: 0]
  ------------------
  340|  10.6k|                uint32_t magic_u32;
  341|  10.6k|                memcpy(&magic_u32, magic, 4);
  342|  10.6k|                if (data_u32[0] == magic_u32 || data_u32[0] == ByteSwap::Swapped(magic_u32)) {
  ------------------
  |  Branch (342:21): [True: 6.54k, False: 4.09k]
  |  Branch (342:49): [True: 0, False: 4.09k]
  ------------------
  343|  6.54k|                    return true;
  344|  6.54k|                }
  345|  10.6k|            } 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.09k|            magic += size;
  352|  4.09k|        }
  353|  10.6k|    }
  354|  4.09k|    return false;
  355|  10.6k|}
BaseImporter.cpp:_ZN12_GLOBAL__N_116StripVersionHashERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
   75|  10.6k|std::string StripVersionHash(const std::string &filename) {
   76|  10.6k|    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|  10.6k|    if (pos != std::string::npos && pos > filename.find_last_of('.') &&
  ------------------
  |  Branch (79:9): [True: 0, False: 10.6k]
  |  Branch (79:9): [True: 0, False: 10.6k]
  |  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|  10.6k|    return filename;
   84|  10.6k|}

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

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

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

_ZN6Assimp6Logger5debugEPKc:
  166|  61.8k|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|  61.8k|    if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) {
  ------------------
  |  Branch (171:9): [True: 0, False: 61.8k]
  ------------------
  172|      0|        return OnDebug("<fixme: long message discarded>");
  173|      0|    }
  174|  61.8k|    return OnDebug(message);
  175|  61.8k|}
_ZN6Assimp6Logger4infoEPKc:
  188|   172k|void Logger::info(const char *message) {
  189|       |
  190|       |    // SECURITY FIX: see above
  191|   172k|    if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) {
  ------------------
  |  Branch (191:9): [True: 0, False: 172k]
  ------------------
  192|      0|        return OnInfo("<fixme: long message discarded>");
  193|      0|    }
  194|   172k|    return OnInfo(message);
  195|   172k|}
_ZN6Assimp6Logger4warnEPKc:
  198|  3.55k|void Logger::warn(const char *message) {
  199|       |
  200|       |    // SECURITY FIX: see above
  201|  3.55k|    if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) {
  ------------------
  |  Branch (201:9): [True: 0, False: 3.55k]
  ------------------
  202|      0|        return OnWarn("<fixme: long message discarded>");
  203|      0|    }
  204|  3.55k|    return OnWarn(message);
  205|  3.55k|}
_ZN6Assimp6Logger5errorEPKc:
  208|  4.58k|void Logger::error(const char *message) {
  209|       |    // SECURITY FIX: see above
  210|  4.58k|    if (strlen(message) > MAX_LOG_MESSAGE_LENGTH) {
  ------------------
  |  Branch (210:9): [True: 1, False: 4.58k]
  ------------------
  211|      1|        return OnError("<fixme: long message discarded>");
  212|      1|    }
  213|  4.58k|    return OnError(message);
  214|  4.58k|}
_ZN6Assimp13DefaultLogger12isNullLoggerEv:
  232|  8.68k|bool DefaultLogger::isNullLogger() {
  233|  8.68k|    return m_pLogger == &s_pNullLogger;
  234|  8.68k|}
_ZN6Assimp13DefaultLogger3getEv:
  237|   242k|Logger *DefaultLogger::get() {
  238|   242k|    return m_pLogger;
  239|   242k|}

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

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

_ZN6Assimp16FileSystemFilterC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEPNS_8IOSystemE:
   68|  2.25k|    : mWrapped  (old)
   69|  2.25k|    , mSrc_file(file)
   70|  2.25k|    , mSep(mWrapped->getOsSeparator()) {
   71|  2.25k|        ai_assert(nullptr != mWrapped);
   72|       |
   73|       |        // Determine base directory
   74|  2.25k|        mBase = mSrc_file;
   75|  2.25k|        std::string::size_type ss2;
   76|  2.25k|        if (std::string::npos != (ss2 = mBase.find_last_of("\\/")))  {
  ------------------
  |  Branch (76:13): [True: 0, False: 2.25k]
  ------------------
   77|      0|            mBase.erase(ss2,mBase.length()-ss2);
   78|  2.25k|        } else {
   79|  2.25k|            mBase = std::string();
   80|  2.25k|        }
   81|       |
   82|       |        // make sure the directory is terminated properly
   83|  2.25k|        char s;
   84|       |
   85|  2.25k|        if ( mBase.empty() ) {
  ------------------
  |  Branch (85:14): [True: 2.25k, False: 0]
  ------------------
   86|  2.25k|            mBase = ".";
   87|  2.25k|            mBase += getOsSeparator();
   88|  2.25k|        } 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.25k|        DefaultLogger::get()->info("Import root directory is \'", mBase, "\'");
   93|  2.25k|    }
_ZNK6Assimp16FileSystemFilter14getOsSeparatorEv:
  116|  2.25k|    char getOsSeparator() const {
  117|  2.25k|        return mSep;
  118|  2.25k|    }
_ZN6Assimp16FileSystemFilter4OpenEPKcS2_:
  122|  4.50k|    IOStream* Open( const char* pFile, const char* pMode = "rb") {
  123|  4.50k|        ai_assert( nullptr != mWrapped );
  124|  4.50k|        if ( nullptr == pFile || nullptr == pMode ) {
  ------------------
  |  Branch (124:14): [True: 0, False: 4.50k]
  |  Branch (124:34): [True: 0, False: 4.50k]
  ------------------
  125|      0|            return nullptr;
  126|      0|        }
  127|       |
  128|  4.50k|        ai_assert( nullptr != pFile );
  129|  4.50k|        ai_assert( nullptr != pMode );
  130|       |
  131|       |        // First try the unchanged path
  132|  4.50k|        IOStream* s = mWrapped->Open(pFile,pMode);
  133|       |
  134|  4.50k|        if (nullptr == s) {
  ------------------
  |  Branch (134:13): [True: 0, False: 4.50k]
  ------------------
  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.50k|        return s;
  153|  4.50k|    }
_ZN6Assimp16FileSystemFilterD2Ev:
   96|  2.25k|    ~FileSystemFilter() = default;

_ZN6Assimp6Intern22AllocateFromAssimpHeapnwEm:
  114|  33.2k|void* AllocateFromAssimpHeap::operator new ( size_t num_bytes)  {
  115|  33.2k|    return ::operator new(num_bytes);
  116|  33.2k|}
_ZN6Assimp6Intern22AllocateFromAssimpHeapdlEPv:
  127|  33.2k|void AllocateFromAssimpHeap::operator delete ( void* data)  {
  128|  33.2k|    return ::operator delete(data);
  129|  33.2k|}
_ZN6Assimp8ImporterC2Ev:
  150|  3.24k| : pimpl( new ImporterPimpl ) {
  151|  3.24k|    pimpl->mScene = nullptr;
  152|  3.24k|    pimpl->mErrorString = std::string();
  153|       |
  154|       |    // Allocate a default IO handler
  155|  3.24k|    pimpl->mIOHandler = new DefaultIOSystem;
  156|  3.24k|    pimpl->mIsDefaultHandler = true;
  157|  3.24k|    pimpl->bExtraVerbose     = false; // disable extra verbose mode by default
  158|       |
  159|  3.24k|    pimpl->mProgressHandler = new DefaultProgressHandler();
  160|  3.24k|    pimpl->mIsDefaultProgressHandler = true;
  161|       |
  162|  3.24k|    GetImporterInstanceList(pimpl->mImporter);
  163|  3.24k|    GetPostProcessingStepInstanceList(pimpl->mPostProcessingSteps);
  164|       |
  165|       |    // Allocate a SharedPostProcessInfo object and store pointers to it in all post-process steps in the list.
  166|  3.24k|    pimpl->mPPShared = new SharedPostProcessInfo();
  167|  3.24k|    for (std::vector<BaseProcess*>::iterator it =  pimpl->mPostProcessingSteps.begin();
  168|   110k|        it != pimpl->mPostProcessingSteps.end();
  ------------------
  |  Branch (168:9): [True: 106k, False: 3.24k]
  ------------------
  169|   106k|        ++it)   {
  170|       |
  171|   106k|        (*it)->SetSharedData(pimpl->mPPShared);
  172|   106k|    }
  173|  3.24k|}
_ZN6Assimp8ImporterD2Ev:
  177|  3.24k|Importer::~Importer() {
  178|       |    // Delete all import plugins
  179|  3.24k|	DeleteImporterInstanceList(pimpl->mImporter);
  180|       |
  181|       |    // Delete all post-processing plug-ins
  182|   110k|    for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); ++a ) {
  ------------------
  |  Branch (182:30): [True: 106k, False: 3.24k]
  ------------------
  183|   106k|        delete pimpl->mPostProcessingSteps[a];
  184|   106k|    }
  185|       |
  186|       |    // Delete the assigned IO and progress handler
  187|  3.24k|    delete pimpl->mIOHandler;
  188|  3.24k|    delete pimpl->mProgressHandler;
  189|       |
  190|       |    // Kill imported scene. Destructor's should do that recursively
  191|  3.24k|    delete pimpl->mScene;
  192|       |
  193|       |    // Delete shared post-processing data
  194|  3.24k|    delete pimpl->mPPShared;
  195|       |
  196|       |    // and finally the pimpl itself
  197|  3.24k|    delete pimpl;
  198|  3.24k|}
_ZN6Assimp8Importer16UnregisterLoaderEPNS_12BaseImporterE:
  251|   149k|aiReturn Importer::UnregisterLoader(BaseImporter* pImp) {
  252|   149k|    if(!pImp) {
  ------------------
  |  Branch (252:8): [True: 0, False: 149k]
  ------------------
  253|       |        // unregistering a nullptr importer is no problem for us ... really!
  254|      0|        return AI_SUCCESS;
  255|      0|    }
  256|       |
  257|   149k|    ASSIMP_BEGIN_EXCEPTION_REGION();
  258|   149k|    std::vector<BaseImporter*>::iterator it = std::find(pimpl->mImporter.begin(),
  259|   149k|        pimpl->mImporter.end(),pImp);
  260|       |
  261|   149k|    if (it != pimpl->mImporter.end())   {
  ------------------
  |  Branch (261:9): [True: 149k, False: 0]
  ------------------
  262|   149k|        pimpl->mImporter.erase(it);
  263|   149k|        ASSIMP_LOG_INFO("Unregistering custom importer: ");
  264|   149k|        return AI_SUCCESS;
  265|   149k|    }
  266|   149k|    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|   149k|}
_ZN6Assimp8Importer12SetIOHandlerEPNS_8IOSystemE:
  297|  6.48k|void Importer::SetIOHandler( IOSystem* pIOHandler) {
  298|  6.48k|    ai_assert(nullptr != pimpl);
  299|       |
  300|  6.48k|    ASSIMP_BEGIN_EXCEPTION_REGION();
  301|       |    // If the new handler is zero, allocate a default IO implementation.
  302|  6.48k|    if (!pIOHandler) {
  ------------------
  |  Branch (302:9): [True: 0, False: 6.48k]
  ------------------
  303|       |        // Release pointer in the possession of the caller
  304|      0|        pimpl->mIOHandler = new DefaultIOSystem();
  305|      0|        pimpl->mIsDefaultHandler = true;
  306|  6.48k|    } else if (pimpl->mIOHandler != pIOHandler) { // Otherwise register the custom handler
  ------------------
  |  Branch (306:16): [True: 6.48k, False: 0]
  ------------------
  307|  6.48k|        delete pimpl->mIOHandler;
  308|  6.48k|        pimpl->mIOHandler = pIOHandler;
  309|  6.48k|        pimpl->mIsDefaultHandler = false;
  310|  6.48k|    }
  311|  6.48k|    ASSIMP_END_EXCEPTION_REGION(void);
  312|  6.48k|}
_ZNK6Assimp8Importer18GetProgressHandlerEv:
  352|  23.1k|ProgressHandler* Importer::GetProgressHandler() const {
  353|  23.1k|    ai_assert(nullptr != pimpl);
  354|       |
  355|  23.1k|    return pimpl->mProgressHandler;
  356|  23.1k|}
_Z14_ValidateFlagsj:
  368|  1.32k|bool _ValidateFlags(unsigned int pFlags) {
  369|  1.32k|    if (pFlags & aiProcess_GenSmoothNormals && pFlags & aiProcess_GenNormals)   {
  ------------------
  |  Branch (369:9): [True: 1.32k, False: 0]
  |  Branch (369:48): [True: 0, False: 1.32k]
  ------------------
  370|      0|        ASSIMP_LOG_ERROR("#aiProcess_GenSmoothNormals and #aiProcess_GenNormals are incompatible");
  371|      0|        return false;
  372|      0|    }
  373|  1.32k|    if (pFlags & aiProcess_OptimizeGraph && pFlags & aiProcess_PreTransformVertices)    {
  ------------------
  |  Branch (373:9): [True: 0, False: 1.32k]
  |  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.32k|    return true;
  378|  1.32k|}
_ZN6Assimp8Importer18ReadFileFromMemoryEPKvmjPKc:
  485|  3.24k|const aiScene* Importer::ReadFileFromMemory(const void* pBuffer, size_t pLength, unsigned int pFlags, const char* pHint ) {
  486|  3.24k|    ai_assert(nullptr != pimpl);
  487|       |
  488|  3.24k|    IOSystem* io = pimpl->mIOHandler;
  489|  3.24k|    try {
  490|  3.24k|        if (pHint == nullptr) {
  ------------------
  |  Branch (490:13): [True: 0, False: 3.24k]
  ------------------
  491|      0|            pHint = "";
  492|      0|        }
  493|  3.24k|        if (!pBuffer || !pLength || strlen(pHint) > MaxLenHint ) {
  ------------------
  |  Branch (493:13): [True: 0, False: 3.24k]
  |  Branch (493:25): [True: 0, False: 3.24k]
  |  Branch (493:37): [True: 0, False: 3.24k]
  ------------------
  494|      0|            pimpl->mErrorString = "Invalid parameters passed to ReadFileFromMemory()";
  495|      0|            return nullptr;
  496|      0|        }
  497|       |        // prevent deletion of the previous IOHandler
  498|  3.24k|        pimpl->mIOHandler = nullptr;
  499|       |
  500|  3.24k|        SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength,io));
  501|       |
  502|       |        // read the file and recover the previous IOSystem
  503|  3.24k|        static const size_t BufSize(Importer::MaxLenHint + 28);
  504|  3.24k|        char fbuff[BufSize];
  505|  3.24k|        ai_snprintf(fbuff, BufSize, "%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint);
  506|       |
  507|  3.24k|        ReadFile(fbuff,pFlags);
  508|  3.24k|        SetIOHandler(io);
  509|  3.24k|    } 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.24k|    return pimpl->mScene;
  523|  3.24k|}
_Z15WriteLogOpeningRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE:
  526|  3.24k|void WriteLogOpening(const std::string& file) {
  527|       |
  528|  3.24k|    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.24k|    const unsigned int flags = aiGetCompileFlags();
  535|  3.24k|    std::stringstream stream;
  536|  3.24k|    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.24k|           << " "
  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.24k|#ifdef ASSIMP_BUILD_DEBUG
  574|  3.24k|           << " debug"
  575|  3.24k|#endif
  576|       |
  577|  3.24k|           << (flags & ASSIMP_CFLAGS_NOBOOST ? " noboost" : "")
  ------------------
  |  |  105|  3.24k|#define ASSIMP_CFLAGS_NOBOOST           0x8
  ------------------
  |  Branch (577:16): [True: 0, False: 3.24k]
  ------------------
  578|  3.24k|           << (flags & ASSIMP_CFLAGS_SHARED ? " shared" : "")
  ------------------
  |  |   98|  3.24k|#define ASSIMP_CFLAGS_SHARED  0x1
  ------------------
  |  Branch (578:16): [True: 0, False: 3.24k]
  ------------------
  579|  3.24k|           << (flags & ASSIMP_CFLAGS_SINGLETHREADED ? " singlethreaded" : "")
  ------------------
  |  |  107|  3.24k|#define ASSIMP_CFLAGS_SINGLETHREADED    0x10
  ------------------
  |  Branch (579:16): [True: 3.24k, False: 0]
  ------------------
  580|  3.24k|           << (flags & ASSIMP_CFLAGS_DOUBLE_SUPPORT ? " double : " : "single : ");
  ------------------
  |  |  109|  3.24k|#define ASSIMP_CFLAGS_DOUBLE_SUPPORT 0x20
  ------------------
  |  Branch (580:16): [True: 0, False: 3.24k]
  ------------------
  581|       |
  582|       |    ASSIMP_LOG_DEBUG(stream.str());
  583|  3.24k|}
_ZN6Assimp8Importer8ReadFileEPKcj:
  587|  3.24k|const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) {
  588|  3.24k|    ai_assert(nullptr != pimpl);
  589|       |
  590|  3.24k|    ASSIMP_BEGIN_EXCEPTION_REGION();
  591|  3.24k|    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.24k|    WriteLogOpening(pFile);
  600|       |
  601|       |#ifdef ASSIMP_CATCH_GLOBAL_EXCEPTIONS
  602|       |    try
  603|       |#endif // ! ASSIMP_CATCH_GLOBAL_EXCEPTIONS
  604|  3.24k|    {
  605|       |        // Check whether this Importer instance has already loaded
  606|       |        // a scene. In this case we need to delete the old one
  607|  3.24k|        if (pimpl->mScene)  {
  ------------------
  |  Branch (607:13): [True: 0, False: 3.24k]
  ------------------
  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.24k|        if( !pimpl->mIOHandler->Exists( pFile)) {
  ------------------
  |  Branch (614:13): [True: 0, False: 3.24k]
  ------------------
  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.24k|        std::unique_ptr<Profiler> profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME, 0) ? new Profiler() : nullptr);
  ------------------
  |  Branch (621:44): [True: 0, False: 3.24k]
  ------------------
  622|  3.24k|        if (profiler) {
  ------------------
  |  Branch (622:13): [True: 0, False: 3.24k]
  ------------------
  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.24k|        SetPropertyInteger("importerIndex", -1);
  629|  3.24k|        struct ImporterAndIndex {
  630|  3.24k|            BaseImporter * importer;
  631|  3.24k|            unsigned int   index;
  632|  3.24k|        };
  633|  3.24k|        std::vector<ImporterAndIndex> possibleImporters;
  634|  9.72k|        for (unsigned int a = 0; a < pimpl->mImporter.size(); a++)  {
  ------------------
  |  Branch (634:34): [True: 6.48k, False: 3.24k]
  ------------------
  635|       |
  636|       |            // Every importer has a list of supported extensions.
  637|  6.48k|            std::set<std::string> extensions;
  638|  6.48k|            pimpl->mImporter[a]->GetExtensionList(extensions);
  639|       |
  640|  6.48k|            if (BaseImporter::HasExtension(pFile, extensions)) {
  ------------------
  |  Branch (640:17): [True: 6.48k, False: 0]
  ------------------
  641|  6.48k|                ImporterAndIndex candidate = { pimpl->mImporter[a], a };
  642|  6.48k|                possibleImporters.push_back(candidate);
  643|  6.48k|            }
  644|  6.48k|        }
  645|       |
  646|       |        // If just one importer supports this extension, pick it and close the case.
  647|  3.24k|        BaseImporter* imp = nullptr;
  648|  3.24k|        if (1 == possibleImporters.size()) {
  ------------------
  |  Branch (648:13): [True: 0, False: 3.24k]
  ------------------
  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.24k|        else {
  655|  7.39k|            for (std::vector<ImporterAndIndex>::const_iterator it = possibleImporters.begin(); it < possibleImporters.end(); ++it) {
  ------------------
  |  Branch (655:96): [True: 6.40k, False: 990]
  ------------------
  656|  6.40k|                BaseImporter & importer = *it->importer;
  657|       |
  658|  6.40k|                ASSIMP_LOG_INFO("Found a possible importer: " + std::string(importer.GetInfo()->mName) + "; trying signature-based detection");
  659|  6.40k|                if (importer.CanRead( pFile, pimpl->mIOHandler, true)) {
  ------------------
  |  Branch (659:21): [True: 2.25k, False: 4.15k]
  ------------------
  660|  2.25k|                    imp = &importer;
  661|  2.25k|                    SetPropertyInteger("importerIndex", it->index);
  662|  2.25k|                    break;
  663|  2.25k|                }
  664|       |
  665|  6.40k|            }
  666|       |
  667|  3.24k|        }
  668|       |
  669|  3.24k|        if (!imp)   {
  ------------------
  |  Branch (669:13): [True: 990, False: 2.25k]
  ------------------
  670|       |            // not so bad yet ... try format auto detection.
  671|    990|            ASSIMP_LOG_INFO("File extension not known, trying signature-based detection");
  672|  2.97k|            for( unsigned int a = 0; a < pimpl->mImporter.size(); a++)  {
  ------------------
  |  Branch (672:38): [True: 1.98k, False: 990]
  ------------------
  673|  1.98k|                if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, true)) {
  ------------------
  |  Branch (673:21): [True: 0, False: 1.98k]
  ------------------
  674|      0|                    imp = pimpl->mImporter[a];
  675|      0|                    SetPropertyInteger("importerIndex", a);
  676|      0|                    break;
  677|      0|                }
  678|  1.98k|            }
  679|       |            // Put a proper error message if no suitable importer was found
  680|    990|            if( !imp)   {
  ------------------
  |  Branch (680:17): [True: 990, False: 0]
  ------------------
  681|    990|                pimpl->mErrorString = "No suitable reader found for the file format of file \"" + pFile + "\".";
  682|    990|                ASSIMP_LOG_ERROR(pimpl->mErrorString);
  683|    990|                return nullptr;
  684|    990|            }
  685|    990|        }
  686|       |
  687|       |        // Get file size for progress handler
  688|  2.25k|        IOStream * fileIO = pimpl->mIOHandler->Open( pFile );
  689|  2.25k|        uint32_t fileSize = 0;
  690|  2.25k|        if (fileIO)
  ------------------
  |  Branch (690:13): [True: 2.25k, False: 0]
  ------------------
  691|  2.25k|        {
  692|  2.25k|            fileSize = static_cast<uint32_t>(fileIO->FileSize());
  693|  2.25k|            pimpl->mIOHandler->Close( fileIO );
  694|  2.25k|        }
  695|       |
  696|       |        // Dispatch the reading to the worker class for this format
  697|  2.25k|        const aiImporterDesc *desc( imp->GetInfo() );
  698|  2.25k|        std::string ext( "unknown" );
  699|  2.25k|        if ( nullptr != desc ) {
  ------------------
  |  Branch (699:14): [True: 2.25k, False: 0]
  ------------------
  700|  2.25k|            ext = desc->mName;
  701|  2.25k|        }
  702|  2.25k|        ASSIMP_LOG_INFO("Found a matching importer for this file format: ", ext, "." );
  703|  2.25k|        pimpl->mProgressHandler->UpdateFileRead( 0, fileSize );
  704|       |
  705|  2.25k|        if (profiler) {
  ------------------
  |  Branch (705:13): [True: 0, False: 2.25k]
  ------------------
  706|      0|            profiler->BeginRegion("import");
  707|      0|        }
  708|       |
  709|  2.25k|        pimpl->mScene = imp->ReadFile( this, pFile, pimpl->mIOHandler);
  710|  2.25k|        pimpl->mProgressHandler->UpdateFileRead( fileSize, fileSize );
  711|       |
  712|  2.25k|        if (profiler) {
  ------------------
  |  Branch (712:13): [True: 0, False: 2.25k]
  ------------------
  713|      0|            profiler->EndRegion("import");
  714|      0|        }
  715|       |
  716|  2.25k|        SetPropertyString("sourceFilePath", pFile);
  717|       |
  718|       |        // If successful, apply all active post processing steps to the imported data
  719|  2.25k|        if( pimpl->mScene)  {
  ------------------
  |  Branch (719:13): [True: 1.46k, False: 789]
  ------------------
  720|  1.46k|            if (!pimpl->mScene->mMetaData || !pimpl->mScene->mMetaData->HasKey(AI_METADATA_SOURCE_FORMAT)) {
  ------------------
  |  Branch (720:17): [True: 0, False: 1.46k]
  |  Branch (720:46): [True: 1.46k, False: 0]
  ------------------
  721|  1.46k|                if (!pimpl->mScene->mMetaData) {
  ------------------
  |  Branch (721:21): [True: 0, False: 1.46k]
  ------------------
  722|      0|                    pimpl->mScene->mMetaData = new aiMetadata;
  723|      0|                }
  724|  1.46k|                pimpl->mScene->mMetaData->Add(AI_METADATA_SOURCE_FORMAT, aiString(ext));
  725|  1.46k|            }
  726|       |
  727|  1.46k|#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
  728|       |            // The ValidateDS process is an exception. It is executed first, even before ScenePreprocessor is called.
  729|  1.46k|            if (pFlags & aiProcess_ValidateDataStructure) {
  ------------------
  |  Branch (729:17): [True: 1.46k, False: 0]
  ------------------
  730|  1.46k|                ValidateDSProcess ds;
  731|  1.46k|                ds.ExecuteOnScene (this);
  732|  1.46k|                if (!pimpl->mScene) {
  ------------------
  |  Branch (732:21): [True: 139, False: 1.32k]
  ------------------
  733|    139|                    return nullptr;
  734|    139|                }
  735|  1.46k|            }
  736|  1.32k|#endif // ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
  737|       |
  738|       |            // Preprocess the scene and prepare it for post-processing
  739|  1.32k|            if (profiler) {
  ------------------
  |  Branch (739:17): [True: 0, False: 1.32k]
  ------------------
  740|      0|                profiler->BeginRegion("preprocess");
  741|      0|            }
  742|       |
  743|  1.32k|            ScenePreprocessor pre(pimpl->mScene);
  744|  1.32k|            pre.ProcessScene();
  745|       |
  746|  1.32k|            if (profiler) {
  ------------------
  |  Branch (746:17): [True: 0, False: 1.32k]
  ------------------
  747|      0|                profiler->EndRegion("preprocess");
  748|      0|            }
  749|       |
  750|       |            // Ensure that the validation process won't be called twice
  751|  1.32k|            ApplyPostProcessing(pFlags & (~aiProcess_ValidateDataStructure));
  752|  1.32k|        }
  753|       |        // if failed, extract the error string
  754|    789|        else if( !pimpl->mScene) {
  ------------------
  |  Branch (754:18): [True: 789, False: 0]
  ------------------
  755|    789|            pimpl->mErrorString = imp->GetErrorText();
  756|    789|            pimpl->mException = imp->GetException();
  757|    789|        }
  758|       |
  759|       |        // clear any data allocated by post-process steps
  760|  2.11k|        pimpl->mPPShared->Clean();
  761|       |
  762|  2.11k|        if (profiler) {
  ------------------
  |  Branch (762:13): [True: 0, False: 2.11k]
  ------------------
  763|      0|            profiler->EndRegion("total");
  764|      0|        }
  765|  2.11k|    }
  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.11k|    ASSIMP_END_EXCEPTION_REGION_WITH_ERROR_STRING(const aiScene*, pimpl->mErrorString, pimpl->mException);
  783|       |
  784|  2.11k|    return pimpl->mScene;
  785|  3.24k|}
_ZN6Assimp8Importer19ApplyPostProcessingEj:
  790|  1.32k|const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) {
  791|  1.32k|    ai_assert(nullptr != pimpl);
  792|       |
  793|  1.32k|    ASSIMP_BEGIN_EXCEPTION_REGION();
  794|       |    // Return immediately if no scene is active
  795|  1.32k|    if (!pimpl->mScene) {
  ------------------
  |  Branch (795:9): [True: 0, False: 1.32k]
  ------------------
  796|      0|        return nullptr;
  797|      0|    }
  798|       |
  799|       |    // If no flags are given, return the current scene with no further action
  800|  1.32k|    if (!pFlags) {
  ------------------
  |  Branch (800:9): [True: 0, False: 1.32k]
  ------------------
  801|      0|        return pimpl->mScene;
  802|      0|    }
  803|       |
  804|       |    // In debug builds: run basic flag validation
  805|  1.32k|    ai_assert(_ValidateFlags(pFlags));
  806|  1.32k|    ASSIMP_LOG_INFO("Entering post processing pipeline");
  807|       |
  808|  1.32k|#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.32k|    if (pFlags & aiProcess_ValidateDataStructure) {
  ------------------
  |  Branch (811:9): [True: 0, False: 1.32k]
  ------------------
  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.32k|#endif // no validation
  819|  1.32k|#ifdef ASSIMP_BUILD_DEBUG
  820|  1.32k|    if (pimpl->bExtraVerbose)
  ------------------
  |  Branch (820:9): [True: 0, False: 1.32k]
  ------------------
  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.32k|    std::unique_ptr<Profiler> profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME, 0) ? new Profiler() : nullptr);
  ------------------
  |  Branch (833:40): [True: 0, False: 1.32k]
  ------------------
  834|  44.1k|    for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++)   {
  ------------------
  |  Branch (834:30): [True: 42.9k, False: 1.27k]
  ------------------
  835|  42.9k|        BaseProcess* process = pimpl->mPostProcessingSteps[a];
  836|  42.9k|        pimpl->mProgressHandler->UpdatePostProcess(static_cast<int>(a), static_cast<int>(pimpl->mPostProcessingSteps.size()) );
  837|  42.9k|        if( process->IsActive( pFlags)) {
  ------------------
  |  Branch (837:13): [True: 19.4k, False: 23.4k]
  ------------------
  838|  19.4k|            if (profiler) {
  ------------------
  |  Branch (838:17): [True: 0, False: 19.4k]
  ------------------
  839|      0|                profiler->BeginRegion("postprocess");
  840|      0|            }
  841|       |
  842|  19.4k|            process->ExecuteOnScene ( this );
  843|       |
  844|  19.4k|            if (profiler) {
  ------------------
  |  Branch (844:17): [True: 0, False: 19.4k]
  ------------------
  845|      0|                profiler->EndRegion("postprocess");
  846|      0|            }
  847|  19.4k|        }
  848|  42.9k|        if( !pimpl->mScene) {
  ------------------
  |  Branch (848:13): [True: 49, False: 42.8k]
  ------------------
  849|     49|            break;
  850|     49|        }
  851|  42.8k|#ifdef ASSIMP_BUILD_DEBUG
  852|  42.8k|#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
  853|       |        // If the extra verbose mode is active, execute the ValidateDataStructureStep again - after each step
  854|  42.8k|        if (pimpl->bExtraVerbose)   {
  ------------------
  |  Branch (854:13): [True: 0, False: 42.8k]
  ------------------
  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|  42.8k|#endif  // no validation
  865|  42.8k|#endif // ! DEBUG
  866|  42.8k|    }
  867|  1.32k|    pimpl->mProgressHandler->UpdatePostProcess( static_cast<int>(pimpl->mPostProcessingSteps.size()),
  868|  1.32k|        static_cast<int>(pimpl->mPostProcessingSteps.size()) );
  869|       |
  870|       |    // update private scene flags
  871|  1.32k|    if( pimpl->mScene ) {
  ------------------
  |  Branch (871:9): [True: 1.27k, False: 49]
  ------------------
  872|  1.27k|      ScenePriv(pimpl->mScene)->mPPStepsApplied |= pFlags;
  873|  1.27k|    }
  874|       |
  875|       |    // clear any data allocated by post-process steps
  876|  1.32k|    pimpl->mPPShared->Clean();
  877|  1.32k|    ASSIMP_LOG_INFO("Leaving post processing pipeline");
  878|       |
  879|  1.32k|    ASSIMP_END_EXCEPTION_REGION(const aiScene*);
  880|       |
  881|  1.32k|    return pimpl->mScene;
  882|  1.32k|}
_ZNK6Assimp8Importer16GetImporterCountEv:
  969|  3.24k|size_t Importer::GetImporterCount() const {
  970|  3.24k|    ai_assert(nullptr != pimpl);
  971|       |
  972|  3.24k|    return pimpl->mImporter.size();
  973|  3.24k|}
_ZNK6Assimp8Importer15GetImporterInfoEm:
  976|   155k|const aiImporterDesc* Importer::GetImporterInfo(size_t index) const {
  977|   155k|    ai_assert(nullptr != pimpl);
  978|       |
  979|   155k|    if (index >= pimpl->mImporter.size()) {
  ------------------
  |  Branch (979:9): [True: 0, False: 155k]
  ------------------
  980|      0|        return nullptr;
  981|      0|    }
  982|   155k|    return pimpl->mImporter[index]->GetInfo();
  983|   155k|}
_ZNK6Assimp8Importer11GetImporterEm:
  987|   155k|BaseImporter* Importer::GetImporter (size_t index) const {
  988|   155k|    ai_assert(nullptr != pimpl);
  989|       |
  990|   155k|    if (index >= pimpl->mImporter.size()) {
  ------------------
  |  Branch (990:9): [True: 0, False: 155k]
  ------------------
  991|      0|        return nullptr;
  992|      0|    }
  993|   155k|    return pimpl->mImporter[index];
  994|   155k|}
_ZN6Assimp8Importer18SetPropertyIntegerEPKci:
 1063|  5.49k|bool Importer::SetPropertyInteger(const char* szName, int iValue) {
 1064|  5.49k|    ai_assert(nullptr != pimpl);
 1065|       |
 1066|  5.49k|    bool existing;
 1067|  5.49k|    ASSIMP_BEGIN_EXCEPTION_REGION();
 1068|  5.49k|        existing = SetGenericProperty<int>(pimpl->mIntProperties, szName,iValue);
 1069|  5.49k|    ASSIMP_END_EXCEPTION_REGION(bool);
 1070|  5.49k|    return existing;
 1071|  5.49k|}
_ZN6Assimp8Importer16SetPropertyFloatEPKcf:
 1075|  1.46k|bool Importer::SetPropertyFloat(const char* szName, ai_real iValue) {
 1076|  1.46k|    ai_assert(nullptr != pimpl);
 1077|       |
 1078|  1.46k|    bool existing;
 1079|  1.46k|    ASSIMP_BEGIN_EXCEPTION_REGION();
 1080|  1.46k|        existing = SetGenericProperty<ai_real>(pimpl->mFloatProperties, szName,iValue);
 1081|  1.46k|    ASSIMP_END_EXCEPTION_REGION(bool);
 1082|  1.46k|    return existing;
 1083|  1.46k|}
_ZN6Assimp8Importer17SetPropertyStringEPKcRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
 1087|  2.25k|bool Importer::SetPropertyString(const char* szName, const std::string& value) {
 1088|  2.25k|    ai_assert(nullptr != pimpl);
 1089|       |
 1090|  2.25k|    bool existing;
 1091|  2.25k|    ASSIMP_BEGIN_EXCEPTION_REGION();
 1092|  2.25k|        existing = SetGenericProperty<std::string>(pimpl->mStringProperties, szName,value);
 1093|  2.25k|    ASSIMP_END_EXCEPTION_REGION(bool);
 1094|  2.25k|    return existing;
 1095|  2.25k|}
_ZNK6Assimp8Importer18GetPropertyIntegerEPKci:
 1123|  17.5k|int Importer::GetPropertyInteger(const char* szName, int iErrorReturn /*= 0xffffffff*/) const {
 1124|  17.5k|    ai_assert(nullptr != pimpl);
 1125|       |
 1126|  17.5k|    return GetGenericProperty<int>(pimpl->mIntProperties,szName,iErrorReturn);
 1127|  17.5k|}
_ZNK6Assimp8Importer16GetPropertyFloatEPKcf:
 1131|  3.87k|ai_real Importer::GetPropertyFloat(const char* szName, ai_real iErrorReturn /*= 10e10*/) const {
 1132|  3.87k|    ai_assert(nullptr != pimpl);
 1133|       |
 1134|  3.87k|    return GetGenericProperty<ai_real>(pimpl->mFloatProperties,szName,iErrorReturn);
 1135|  3.87k|}
_ZNK6Assimp8Importer17GetPropertyStringEPKcRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
 1139|  1.32k|std::string Importer::GetPropertyString(const char* szName, const std::string& iErrorReturn /*= ""*/) const {
 1140|  1.32k|    ai_assert(nullptr != pimpl);
 1141|       |
 1142|  1.32k|    return GetGenericProperty<std::string>(pimpl->mStringProperties,szName,iErrorReturn);
 1143|  1.32k|}
_ZNK6Assimp8Importer18GetPropertyPointerEPKcPv:
 1155|  2.17k|void* Importer::GetPropertyPointer(const char* szName, void* iErrorReturn /*= nullptr*/) const {
 1156|  2.17k|    ai_assert(nullptr != pimpl);
 1157|       |
 1158|  2.17k|    return GetGenericProperty<void*>(pimpl->mPointerProperties,szName,iErrorReturn);
 1159|  2.17k|}

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

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

_ZN6Assimp33GetPostProcessingStepInstanceListERNSt3__16vectorIPNS_11BaseProcessENS0_9allocatorIS3_EEEE:
  147|  3.24k|{
  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.24k|    out.reserve(31);
  154|  3.24k|#if (!defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS)
  155|  3.24k|    out.push_back( new MakeLeftHandedProcess());
  156|  3.24k|#endif
  157|  3.24k|#if (!defined ASSIMP_BUILD_NO_FLIPUVS_PROCESS)
  158|  3.24k|    out.push_back( new FlipUVsProcess());
  159|  3.24k|#endif
  160|  3.24k|#if (!defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS)
  161|  3.24k|    out.push_back( new FlipWindingOrderProcess());
  162|  3.24k|#endif
  163|  3.24k|#if (!defined ASSIMP_BUILD_NO_REMOVEVC_PROCESS)
  164|  3.24k|    out.push_back( new RemoveVCProcess());
  165|  3.24k|#endif
  166|  3.24k|#if (!defined ASSIMP_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS)
  167|  3.24k|    out.push_back( new RemoveRedundantMatsProcess());
  168|  3.24k|#endif
  169|  3.24k|#if (!defined ASSIMP_BUILD_NO_EMBEDTEXTURES_PROCESS)
  170|  3.24k|    out.push_back( new EmbedTexturesProcess());
  171|  3.24k|#endif
  172|  3.24k|#if (!defined ASSIMP_BUILD_NO_FINDINSTANCES_PROCESS)
  173|  3.24k|    out.push_back( new FindInstancesProcess());
  174|  3.24k|#endif
  175|  3.24k|#if (!defined ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS)
  176|  3.24k|    out.push_back( new OptimizeGraphProcess());
  177|  3.24k|#endif
  178|  3.24k|#ifndef ASSIMP_BUILD_NO_GENUVCOORDS_PROCESS
  179|  3.24k|    out.push_back( new ComputeUVMappingProcess());
  180|  3.24k|#endif
  181|  3.24k|#ifndef ASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS
  182|  3.24k|    out.push_back( new TextureTransformStep());
  183|  3.24k|#endif
  184|  3.24k|#if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS)
  185|  3.24k|    out.push_back( new ScaleProcess());
  186|  3.24k|#endif
  187|  3.24k|#if (!defined ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS)
  188|  3.24k|    out.push_back( new ArmaturePopulate());
  189|  3.24k|#endif
  190|  3.24k|#if (!defined ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS)
  191|  3.24k|    out.push_back( new PretransformVertices());
  192|  3.24k|#endif
  193|  3.24k|#if (!defined ASSIMP_BUILD_NO_TRIANGULATE_PROCESS)
  194|  3.24k|    out.push_back( new TriangulateProcess());
  195|  3.24k|#endif
  196|  3.24k|#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.24k|    out.push_back( new FindDegeneratesProcess());
  201|  3.24k|#endif
  202|  3.24k|#if (!defined ASSIMP_BUILD_NO_SORTBYPTYPE_PROCESS)
  203|  3.24k|    out.push_back( new SortByPTypeProcess());
  204|  3.24k|#endif
  205|  3.24k|#if (!defined ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS)
  206|  3.24k|    out.push_back( new FindInvalidDataProcess());
  207|  3.24k|#endif
  208|  3.24k|#if (!defined ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS)
  209|  3.24k|    out.push_back( new OptimizeMeshesProcess());
  210|  3.24k|#endif
  211|  3.24k|#if (!defined ASSIMP_BUILD_NO_FIXINFACINGNORMALS_PROCESS)
  212|  3.24k|    out.push_back( new FixInfacingNormalsProcess());
  213|  3.24k|#endif
  214|  3.24k|#if (!defined ASSIMP_BUILD_NO_SPLITBYBONECOUNT_PROCESS)
  215|  3.24k|    out.push_back( new SplitByBoneCountProcess());
  216|  3.24k|#endif
  217|  3.24k|#if (!defined ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS)
  218|  3.24k|    out.push_back( new SplitLargeMeshesProcess_Triangle());
  219|  3.24k|#endif
  220|  3.24k|#if (!defined ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS)
  221|  3.24k|    out.push_back( new DropFaceNormalsProcess());
  222|  3.24k|#endif
  223|  3.24k|#if (!defined ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS)
  224|  3.24k|    out.push_back( new GenFaceNormalsProcess());
  225|  3.24k|#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.24k|    out.push_back( new ComputeSpatialSortProcess());
  232|       |    // .........................................................................
  233|       |
  234|  3.24k|#if (!defined ASSIMP_BUILD_NO_GENVERTEXNORMALS_PROCESS)
  235|  3.24k|    out.push_back( new GenVertexNormalsProcess());
  236|  3.24k|#endif
  237|  3.24k|#if (!defined ASSIMP_BUILD_NO_CALCTANGENTS_PROCESS)
  238|  3.24k|    out.push_back( new CalcTangentsProcess());
  239|  3.24k|#endif
  240|  3.24k|#if (!defined ASSIMP_BUILD_NO_JOINVERTICES_PROCESS)
  241|  3.24k|    out.push_back( new JoinVerticesProcess());
  242|  3.24k|#endif
  243|       |
  244|       |    // .........................................................................
  245|  3.24k|    out.push_back( new DestroySpatialSortProcess());
  246|       |    // .........................................................................
  247|       |
  248|  3.24k|#if (!defined ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS)
  249|  3.24k|    out.push_back( new SplitLargeMeshesProcess_Vertex());
  250|  3.24k|#endif
  251|  3.24k|#if (!defined ASSIMP_BUILD_NO_DEBONE_PROCESS)
  252|  3.24k|    out.push_back( new DeboneProcess());
  253|  3.24k|#endif
  254|  3.24k|#if (!defined ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS)
  255|  3.24k|    out.push_back( new LimitBoneWeightsProcess());
  256|  3.24k|#endif
  257|  3.24k|#if (!defined ASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS)
  258|  3.24k|    out.push_back( new ImproveCacheLocalityProcess());
  259|  3.24k|#endif
  260|  3.24k|#if (!defined ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS)
  261|  3.24k|    out.push_back(new GenBoundingBoxesProcess);
  262|  3.24k|#endif
  263|  3.24k|}

_ZN6Assimp17ScenePreprocessor12ProcessSceneEv:
   50|  1.32k|void ScenePreprocessor::ProcessScene() {
   51|  1.32k|    ai_assert(scene != nullptr);
  ------------------
  |  |   67|  1.32k|#   define ai_assert(expression) (void)((!!(expression)) || (Assimp::aiAssertViolation(#expression, __FILE__, __LINE__), 0))
  |  |  ------------------
  |  |  |  Branch (67:41): [True: 1.32k, False: 0]
  |  |  |  Branch (67:61): [True: 0, False: 0]
  |  |  ------------------
  ------------------
   52|       |
   53|       |    // Process all meshes
   54|  2.50k|    for (unsigned int i = 0; i < scene->mNumMeshes; ++i) {
  ------------------
  |  Branch (54:30): [True: 1.17k, False: 1.32k]
  ------------------
   55|  1.17k|        if (nullptr == scene->mMeshes[i]) {
  ------------------
  |  Branch (55:13): [True: 0, False: 1.17k]
  ------------------
   56|      0|            continue;
   57|      0|        }
   58|  1.17k|        ProcessMesh(scene->mMeshes[i]);
   59|  1.17k|    }
   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.32k|    for (unsigned int i = 0; i < scene->mNumAnimations; ++i) {
  ------------------
  |  Branch (67:30): [True: 0, False: 1.32k]
  ------------------
   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.32k|    if (!scene->mNumMaterials && scene->mNumMeshes) {
  ------------------
  |  Branch (75:9): [True: 0, False: 1.32k]
  |  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.32k|}
_ZN6Assimp17ScenePreprocessor11ProcessMeshEP6aiMesh:
  103|  1.17k|void ScenePreprocessor::ProcessMesh(aiMesh *mesh) {
  104|       |    // If aiMesh::mNumUVComponents is *not* set assign the default value of 2
  105|  10.6k|    for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
  ------------------
  |  Branch (105:30): [True: 9.43k, False: 1.17k]
  ------------------
  106|  9.43k|        if (!mesh->mTextureCoords[i]) {
  ------------------
  |  Branch (106:13): [True: 9.08k, False: 352]
  ------------------
  107|  9.08k|            mesh->mNumUVComponents[i] = 0;
  108|  9.08k|            continue;
  109|  9.08k|        }
  110|       |
  111|    352|        if (!mesh->mNumUVComponents[i]) {
  ------------------
  |  Branch (111:13): [True: 0, False: 352]
  ------------------
  112|      0|            mesh->mNumUVComponents[i] = 2;
  113|      0|        }
  114|       |
  115|    352|        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|    352|        if (2 == mesh->mNumUVComponents[i]) {
  ------------------
  |  Branch (120:13): [True: 275, False: 77]
  ------------------
  121|  2.93k|            for (; p != end; ++p) {
  ------------------
  |  Branch (121:20): [True: 2.66k, False: 275]
  ------------------
  122|  2.66k|                p->z = 0.f;
  123|  2.66k|            }
  124|    275|        } else if (1 == mesh->mNumUVComponents[i]) {
  ------------------
  |  Branch (124:20): [True: 54, False: 23]
  ------------------
  125|    785|            for (; p != end; ++p) {
  ------------------
  |  Branch (125:20): [True: 731, False: 54]
  ------------------
  126|    731|                p->z = p->y = 0.f;
  127|    731|            }
  128|     54|        } else if (3 == mesh->mNumUVComponents[i]) {
  ------------------
  |  Branch (128:20): [True: 15, False: 8]
  ------------------
  129|       |            // Really 3D coordinates? Check whether the third coordinate is != 0 for at least one element
  130|    139|            for (; p != end; ++p) {
  ------------------
  |  Branch (130:20): [True: 133, False: 6]
  ------------------
  131|    133|                if (p->z != 0) {
  ------------------
  |  Branch (131:21): [True: 9, False: 124]
  ------------------
  132|      9|                    break;
  133|      9|                }
  134|    133|            }
  135|     15|            if (p == end) {
  ------------------
  |  Branch (135:17): [True: 6, False: 9]
  ------------------
  136|      6|                ASSIMP_LOG_WARN("ScenePreprocessor: UVs are declared to be 3D but they're obviously not. Reverting to 2D.");
  137|      6|                mesh->mNumUVComponents[i] = 2;
  138|      6|            }
  139|     15|        }
  140|    352|    }
  141|       |
  142|       |    // If the information which primitive types are there in the
  143|       |    // mesh is currently not available, compute it.
  144|  1.17k|    if (!mesh->mPrimitiveTypes) {
  ------------------
  |  Branch (144:9): [True: 0, False: 1.17k]
  ------------------
  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.17k|    if (mesh->mTangents && mesh->mNormals && !mesh->mBitangents) {
  ------------------
  |  Branch (169:9): [True: 29, False: 1.15k]
  |  Branch (169:28): [True: 29, False: 0]
  |  Branch (169:46): [True: 0, False: 29]
  ------------------
  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.17k|}

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

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

_ZN6Assimp11SpatialSortC2Ev:
   69|  2.61k|        mPlaneNormal(PlaneInit),
   70|  2.61k|        mFinalized(false) {
   71|  2.61k|    mPlaneNormal.Normalize();
   72|  2.61k|}
_ZN6Assimp11SpatialSort4FillEPK10aiVector3tIfEjjb:
   77|  1.89k|        bool pFinalize /*= true */) {
   78|  1.89k|    mPositions.clear();
   79|  1.89k|    mFinalized = false;
   80|  1.89k|    Append(pPositions, pNumPositions, pElementOffset, pFinalize);
   81|  1.89k|    mFinalized = pFinalize;
   82|  1.89k|}
_ZNK6Assimp11SpatialSort17CalculateDistanceERK10aiVector3tIfE:
   85|  94.6k|ai_real SpatialSort::CalculateDistance(const aiVector3D &pPosition) const {
   86|  94.6k|    return (pPosition - mCentroid) * mPlaneNormal;
   87|  94.6k|}
_ZN6Assimp11SpatialSort8FinalizeEv:
   90|  1.89k|void SpatialSort::Finalize() {
   91|  1.89k|    const ai_real scale = 1.0f / mPositions.size();
   92|  58.0k|    for (unsigned int i = 0; i < mPositions.size(); i++) {
  ------------------
  |  Branch (92:30): [True: 56.1k, False: 1.89k]
  ------------------
   93|  56.1k|        mCentroid += scale * mPositions[i].mPosition;
   94|  56.1k|    }
   95|  58.0k|    for (unsigned int i = 0; i < mPositions.size(); i++) {
  ------------------
  |  Branch (95:30): [True: 56.1k, False: 1.89k]
  ------------------
   96|  56.1k|        mPositions[i].mDistance = CalculateDistance(mPositions[i].mPosition);
   97|  56.1k|    }
   98|  1.89k|    std::sort(mPositions.begin(), mPositions.end());
   99|  1.89k|    mFinalized = true;
  100|  1.89k|}
_ZN6Assimp11SpatialSort6AppendEPK10aiVector3tIfEjjb:
  105|  1.89k|        bool pFinalize /*= true */) {
  106|  1.89k|    ai_assert(!mFinalized && "You cannot add positions to the SpatialSort object after it has been finalized.");
  ------------------
  |  |   67|  3.78k|#   define ai_assert(expression) (void)((!!(expression)) || (Assimp::aiAssertViolation(#expression, __FILE__, __LINE__), 0))
  |  |  ------------------
  |  |  |  Branch (67:45): [True: 1.89k, 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|  1.89k|    const size_t initial = mPositions.size();
  109|  1.89k|    mPositions.reserve(initial + pNumPositions);
  110|  58.0k|    for (unsigned int a = 0; a < pNumPositions; a++) {
  ------------------
  |  Branch (110:30): [True: 56.1k, False: 1.89k]
  ------------------
  111|  56.1k|        const char *tempPointer = reinterpret_cast<const char *>(pPositions);
  112|  56.1k|        const aiVector3D *vec = reinterpret_cast<const aiVector3D *>(tempPointer + a * pElementOffset);
  113|  56.1k|        mPositions.emplace_back(static_cast<unsigned int>(a + initial), *vec);
  114|  56.1k|    }
  115|       |
  116|  1.89k|    if (pFinalize) {
  ------------------
  |  Branch (116:9): [True: 1.89k, False: 0]
  ------------------
  117|       |        // now sort the array ascending by distance.
  118|  1.89k|        Finalize();
  119|  1.89k|    }
  120|  1.89k|}
_ZNK6Assimp11SpatialSort13FindPositionsERK10aiVector3tIfEfRNSt3__16vectorIjNS5_9allocatorIjEEEE:
  125|  38.4k|        ai_real pRadius, std::vector<unsigned int> &poResults) const {
  126|  38.4k|    ai_assert(mFinalized && "The SpatialSort object must be finalized before FindPositions can be called.");
  ------------------
  |  |   67|  76.8k|#   define ai_assert(expression) (void)((!!(expression)) || (Assimp::aiAssertViolation(#expression, __FILE__, __LINE__), 0))
  |  |  ------------------
  |  |  |  Branch (67:45): [True: 38.4k, False: 0]
  |  |  |  Branch (67:45): [True: 0, Folded]
  |  |  |  Branch (67:61): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  127|  38.4k|    const ai_real dist = CalculateDistance(pPosition);
  128|  38.4k|    const ai_real minDist = dist - pRadius, maxDist = dist + pRadius;
  129|       |
  130|       |    // clear the array
  131|  38.4k|    poResults.clear();
  132|       |
  133|       |    // quick check for positions outside the range
  134|  38.4k|    if (mPositions.size() == 0)
  ------------------
  |  Branch (134:9): [True: 0, False: 38.4k]
  ------------------
  135|      0|        return;
  136|  38.4k|    if (maxDist < mPositions.front().mDistance)
  ------------------
  |  Branch (136:9): [True: 0, False: 38.4k]
  ------------------
  137|      0|        return;
  138|  38.4k|    if (minDist > mPositions.back().mDistance)
  ------------------
  |  Branch (138:9): [True: 0, False: 38.4k]
  ------------------
  139|      0|        return;
  140|       |
  141|       |    // do a binary search for the minimal distance to start the iteration there
  142|  38.4k|    unsigned int index = (unsigned int)mPositions.size() / 2;
  143|  38.4k|    unsigned int binaryStepSize = (unsigned int)mPositions.size() / 4;
  144|   210k|    while (binaryStepSize > 1) {
  ------------------
  |  Branch (144:12): [True: 172k, False: 38.4k]
  ------------------
  145|   172k|        if (mPositions[index].mDistance < minDist)
  ------------------
  |  Branch (145:13): [True: 75.8k, False: 96.2k]
  ------------------
  146|  75.8k|            index += binaryStepSize;
  147|  96.2k|        else
  148|  96.2k|            index -= binaryStepSize;
  149|       |
  150|   172k|        binaryStepSize /= 2;
  151|   172k|    }
  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|  53.0k|    while (index > 0 && mPositions[index].mDistance > minDist)
  ------------------
  |  Branch (155:12): [True: 49.7k, False: 3.29k]
  |  Branch (155:25): [True: 14.5k, False: 35.1k]
  ------------------
  156|  14.5k|        index--;
  157|  74.3k|    while (index < (mPositions.size() - 1) && mPositions[index].mDistance < minDist)
  ------------------
  |  Branch (157:12): [True: 74.1k, False: 178]
  |  Branch (157:47): [True: 35.9k, False: 38.2k]
  ------------------
  158|  35.9k|        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|  38.4k|    std::vector<Entry>::const_iterator it = mPositions.begin() + index;
  163|  38.4k|    const ai_real pSquared = pRadius * pRadius;
  164|   160k|    while (it->mDistance < maxDist) {
  ------------------
  |  Branch (164:12): [True: 124k, False: 35.4k]
  ------------------
  165|   124k|        if ((it->mPosition - pPosition).SquareLength() < pSquared)
  ------------------
  |  Branch (165:13): [True: 35.6k, False: 89.2k]
  ------------------
  166|  35.6k|            poResults.push_back(it->mIndex);
  167|   124k|        ++it;
  168|   124k|        if (it == mPositions.end())
  ------------------
  |  Branch (168:13): [True: 3.01k, False: 121k]
  ------------------
  169|  3.01k|            break;
  170|   124k|    }
  171|       |
  172|       |    // that's it
  173|  38.4k|}

aiGetVersionMinor:
   72|  3.24k|ASSIMP_API unsigned int aiGetVersionMinor() {
   73|  3.24k|    return VER_MINOR;
  ------------------
  |  |    8|  3.24k|#define VER_MINOR 0
  ------------------
   74|  3.24k|}
aiGetVersionMajor:
   78|  3.24k|ASSIMP_API unsigned int aiGetVersionMajor() {
   79|  3.24k|    return VER_MAJOR;
  ------------------
  |  |    7|  3.24k|#define VER_MAJOR 6
  ------------------
   80|  3.24k|}
aiGetCompileFlags:
   84|  3.24k|ASSIMP_API unsigned int aiGetCompileFlags() {
   85|       |
   86|  3.24k|    unsigned int flags = 0;
   87|       |
   88|       |#ifdef ASSIMP_BUILD_BOOST_WORKAROUND
   89|       |    flags |= ASSIMP_CFLAGS_NOBOOST;
   90|       |#endif
   91|  3.24k|#ifdef ASSIMP_BUILD_SINGLETHREADED
   92|  3.24k|    flags |= ASSIMP_CFLAGS_SINGLETHREADED;
  ------------------
  |  |  107|  3.24k|#define ASSIMP_CFLAGS_SINGLETHREADED    0x10
  ------------------
   93|  3.24k|#endif
   94|  3.24k|#ifdef ASSIMP_BUILD_DEBUG
   95|  3.24k|    flags |= ASSIMP_CFLAGS_DEBUG;
  ------------------
  |  |  102|  3.24k|#define ASSIMP_CFLAGS_DEBUG   0x4
  ------------------
   96|  3.24k|#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.24k|    return flags;
  108|  3.24k|}
aiGetVersionRevision:
  111|  3.24k|ASSIMP_API unsigned int aiGetVersionRevision() {
  112|  3.24k|    return GitVersion;
  ------------------
  |  |    4|  3.24k|#define GitVersion 0x8ff00557
  ------------------
  113|  3.24k|}

_ZN6Assimp23VertexTriangleAdjacencyC2EP6aiFacejjb:
   55|    370|        bool bComputeNumTriangles /*= false*/) {
   56|       |    // compute the number of referenced vertices if it wasn't specified by the caller
   57|    370|    const aiFace *const pcFaceEnd = pcFaces + iNumFaces;
   58|    370|    if (0 == iNumVertices) {
  ------------------
  |  Branch (58:9): [True: 0, False: 370]
  ------------------
   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|    370|    mNumVertices = iNumVertices + 1;
   69|       |
   70|    370|    unsigned int *pi;
   71|       |
   72|       |    // allocate storage
   73|    370|    if (bComputeNumTriangles) {
  ------------------
  |  Branch (73:9): [True: 370, False: 0]
  ------------------
   74|    370|        pi = mLiveTriangles = new unsigned int[iNumVertices + 1];
   75|    370|        ::memset(mLiveTriangles, 0, sizeof(unsigned int) * (iNumVertices + 1));
   76|    370|        mOffsetTable = new unsigned int[iNumVertices + 2] + 1;
   77|    370|    } 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|    370|    unsigned int *piEnd = pi + iNumVertices;
   85|    370|    *piEnd++ = 0u;
   86|       |
   87|       |    // first pass: compute the number of faces referencing each vertex
   88|  14.1k|    for (aiFace *pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace) {
  ------------------
  |  Branch (88:36): [True: 13.8k, False: 370]
  ------------------
   89|  13.8k|        unsigned nind = pcFace->mNumIndices;
   90|  13.8k|        unsigned *ind = pcFace->mIndices;
   91|  13.8k|        if (nind > 0) pi[ind[0]]++;
  ------------------
  |  Branch (91:13): [True: 13.8k, False: 0]
  ------------------
   92|  13.8k|        if (nind > 1) pi[ind[1]]++;
  ------------------
  |  Branch (92:13): [True: 13.8k, False: 0]
  ------------------
   93|  13.8k|        if (nind > 2) pi[ind[2]]++;
  ------------------
  |  Branch (93:13): [True: 13.8k, False: 0]
  ------------------
   94|  13.8k|    }
   95|       |
   96|       |    // second pass: compute the final offset table
   97|    370|    unsigned int iSum = 0;
   98|    370|    unsigned int *piCurOut = this->mOffsetTable;
   99|  11.9k|    for (unsigned int *piCur = pi; piCur != piEnd; ++piCur, ++piCurOut) {
  ------------------
  |  Branch (99:36): [True: 11.6k, False: 370]
  ------------------
  100|       |
  101|  11.6k|        unsigned int iLastSum = iSum;
  102|  11.6k|        iSum += *piCur;
  103|  11.6k|        *piCurOut = iLastSum;
  104|  11.6k|    }
  105|    370|    pi = this->mOffsetTable;
  106|       |
  107|       |    // third pass: compute the final table
  108|    370|    this->mAdjacencyTable = new unsigned int[iSum];
  109|    370|    iSum = 0;
  110|  14.1k|    for (aiFace *pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace, ++iSum) {
  ------------------
  |  Branch (110:36): [True: 13.8k, False: 370]
  ------------------
  111|  13.8k|        unsigned nind = pcFace->mNumIndices;
  112|  13.8k|        unsigned *ind = pcFace->mIndices;
  113|       |
  114|  13.8k|        if (nind > 0) mAdjacencyTable[pi[ind[0]]++] = iSum;
  ------------------
  |  Branch (114:13): [True: 13.8k, False: 0]
  ------------------
  115|  13.8k|        if (nind > 1) mAdjacencyTable[pi[ind[1]]++] = iSum;
  ------------------
  |  Branch (115:13): [True: 13.8k, False: 0]
  ------------------
  116|  13.8k|        if (nind > 2) mAdjacencyTable[pi[ind[2]]++] = iSum;
  ------------------
  |  Branch (116:13): [True: 13.8k, False: 0]
  ------------------
  117|  13.8k|    }
  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|    370|    --mOffsetTable;
  121|    370|    *mOffsetTable = 0u;
  122|    370|}
_ZN6Assimp23VertexTriangleAdjacencyD2Ev:
  124|    370|VertexTriangleAdjacency::~VertexTriangleAdjacency() {
  125|       |    // delete allocated storage
  126|    370|    delete[] mOffsetTable;
  127|    370|    delete[] mAdjacencyTable;
  128|    370|    delete[] mLiveTriangles;
  129|    370|}

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

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

_ZN7aiSceneC2Ev:
   46|  2.25k|        mFlags(0),
   47|  2.25k|        mRootNode(nullptr),
   48|  2.25k|        mNumMeshes(0),
   49|  2.25k|        mMeshes(nullptr),
   50|  2.25k|        mNumMaterials(0),
   51|  2.25k|        mMaterials(nullptr),
   52|  2.25k|        mNumAnimations(0),
   53|  2.25k|        mAnimations(nullptr),
   54|  2.25k|        mNumTextures(0),
   55|  2.25k|        mTextures(nullptr),
   56|  2.25k|        mNumLights(0),
   57|  2.25k|        mLights(nullptr),
   58|  2.25k|        mNumCameras(0),
   59|  2.25k|        mCameras(nullptr),
   60|  2.25k|        mMetaData(nullptr),
   61|  2.25k|        mName(),
   62|  2.25k|        mNumSkeletons(0),
   63|  2.25k|        mSkeletons(nullptr),
   64|  2.25k|        mPrivate(new Assimp::ScenePrivateData()) {
   65|       |    // empty
   66|  2.25k|}
_ZN7aiSceneD2Ev:
   68|  2.25k|aiScene::~aiScene() {
   69|       |    // delete all sub-objects recursively
   70|  2.25k|    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.25k|    if (mNumMeshes && mMeshes) {
  ------------------
  |  Branch (75:9): [True: 1.28k, False: 971]
  |  Branch (75:23): [True: 1.28k, False: 0]
  ------------------
   76|  3.35k|        for (unsigned int a = 0; a < mNumMeshes; ++a) {
  ------------------
  |  Branch (76:34): [True: 2.07k, False: 1.28k]
  ------------------
   77|  2.07k|            delete mMeshes[a];
   78|  2.07k|        }
   79|  1.28k|    }
   80|  2.25k|    delete[] mMeshes;
   81|       |
   82|  2.25k|    if (mNumMaterials && mMaterials) {
  ------------------
  |  Branch (82:9): [True: 1.74k, False: 510]
  |  Branch (82:26): [True: 1.74k, False: 0]
  ------------------
   83|  3.80k|        for (unsigned int a = 0; a < mNumMaterials; ++a) {
  ------------------
  |  Branch (83:34): [True: 2.06k, False: 1.74k]
  ------------------
   84|  2.06k|            delete mMaterials[a];
   85|  2.06k|        }
   86|  1.74k|    }
   87|  2.25k|    delete[] mMaterials;
   88|       |
   89|  2.25k|    if (mNumAnimations && mAnimations) {
  ------------------
  |  Branch (89:9): [True: 0, False: 2.25k]
  |  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.25k|    delete[] mAnimations;
   95|       |
   96|  2.25k|    if (mNumTextures && mTextures) {
  ------------------
  |  Branch (96:9): [True: 47, False: 2.20k]
  |  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.25k|    delete[] mTextures;
  102|       |
  103|  2.25k|    if (mNumLights && mLights) {
  ------------------
  |  Branch (103:9): [True: 0, False: 2.25k]
  |  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.25k|    delete[] mLights;
  109|       |
  110|  2.25k|    if (mNumCameras && mCameras) {
  ------------------
  |  Branch (110:9): [True: 0, False: 2.25k]
  |  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.25k|    delete[] mCameras;
  116|       |
  117|  2.25k|    aiMetadata::Dealloc(mMetaData);
  118|       |
  119|  2.25k|    delete[] mSkeletons;
  120|       |
  121|  2.25k|    delete static_cast<Assimp::ScenePrivateData *>(mPrivate);
  122|  2.25k|}
_ZN6aiNodeC2ERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
  136|  8.15k|        mName(name),
  137|  8.15k|        mParent(nullptr),
  138|  8.15k|        mNumChildren(0),
  139|  8.15k|        mChildren(nullptr),
  140|  8.15k|        mNumMeshes(0),
  141|  8.15k|        mMeshes(nullptr),
  142|  8.15k|        mMetaData(nullptr) {
  143|       |    // empty
  144|  8.15k|}
_ZN6aiNodeD2Ev:
  147|  8.15k|aiNode::~aiNode() {
  148|       |    // delete all children recursively
  149|       |    // to make sure we won't crash if the data is invalid ...
  150|  8.15k|    if (mNumChildren && mChildren) {
  ------------------
  |  Branch (150:9): [True: 4.00k, False: 4.15k]
  |  Branch (150:25): [True: 4.00k, False: 0]
  ------------------
  151|  10.7k|        for (unsigned int a = 0; a < mNumChildren; a++)
  ------------------
  |  Branch (151:34): [True: 6.76k, False: 4.00k]
  ------------------
  152|  6.76k|            delete mChildren[a];
  153|  4.00k|    }
  154|  8.15k|    delete[] mChildren;
  155|  8.15k|    delete[] mMeshes;
  156|  8.15k|    delete mMetaData;
  157|  8.15k|}

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

aiGetMaterialProperty:
   63|  4.57k|        const aiMaterialProperty **pPropOut) {
   64|  4.57k|    ai_assert(pMat != nullptr);
   65|  4.57k|    ai_assert(pKey != nullptr);
   66|  4.57k|    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|  46.1k|    for (unsigned int i = 0; i < pMat->mNumProperties; ++i) {
  ------------------
  |  Branch (72:30): [True: 46.1k, False: 0]
  ------------------
   73|  46.1k|        aiMaterialProperty *prop = pMat->mProperties[i];
   74|       |
   75|  46.1k|        if (prop /* just for safety ... */
  ------------------
  |  Branch (75:13): [True: 46.1k, False: 0]
  ------------------
   76|  46.1k|                && 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: 4.57k, False: 41.5k]
  |  Branch (76:74): [True: 0, False: 4.57k]
  |  Branch (76:94): [True: 4.57k, False: 0]
  ------------------
   77|  4.57k|                && (UINT_MAX == index || prop->mIndex == index)) {
  ------------------
  |  Branch (77:21): [True: 0, False: 4.57k]
  |  Branch (77:42): [True: 4.57k, False: 0]
  ------------------
   78|  4.57k|            *pPropOut = pMat->mProperties[i];
   79|  4.57k|            return AI_SUCCESS;
   80|  4.57k|        }
   81|  46.1k|    }
   82|      0|    *pPropOut = nullptr;
   83|       |
   84|       |    return AI_FAILURE;
   85|  4.57k|}
aiGetMaterialFloatArray:
  194|  2.28k|        unsigned int *pMax) {
  195|  2.28k|    return GetMaterialFloatArray(pMat, pKey, type, index, pOut, pMax);
  196|  2.28k|}
aiGetMaterialIntegerArray:
  205|  2.28k|        unsigned int *pMax) {
  206|  2.28k|    ai_assert(pOut != nullptr);
  207|  2.28k|    ai_assert(pMat != nullptr);
  208|       |
  209|  2.28k|    const aiMaterialProperty *prop;
  210|  2.28k|    aiGetMaterialProperty(pMat, pKey, type, index, &prop);
  211|  2.28k|    if (!prop) {
  ------------------
  |  Branch (211:9): [True: 0, False: 2.28k]
  ------------------
  212|      0|        return AI_FAILURE;
  213|      0|    }
  214|       |
  215|       |    // data is given in ints, simply copy it
  216|  2.28k|    unsigned int iWrite = 0;
  217|  2.28k|    if (aiPTI_Integer == prop->mType || aiPTI_Buffer == prop->mType) {
  ------------------
  |  Branch (217:9): [True: 0, False: 2.28k]
  |  Branch (217:41): [True: 2.28k, False: 0]
  ------------------
  218|  2.28k|        iWrite = std::max(static_cast<unsigned int>(prop->mDataLength / sizeof(int32_t)), 1u);
  219|  2.28k|        if (pMax) {
  ------------------
  |  Branch (219:13): [True: 0, False: 2.28k]
  ------------------
  220|      0|            iWrite = std::min(*pMax, iWrite);
  221|      0|        }
  222|  2.28k|        if (1 == prop->mDataLength) {
  ------------------
  |  Branch (222:13): [True: 0, False: 2.28k]
  ------------------
  223|       |            // bool type, 1 byte
  224|      0|            *pOut = static_cast<int>(*prop->mData);
  225|  2.28k|        } else {
  226|  4.57k|            for (unsigned int a = 0; a < iWrite; ++a) {
  ------------------
  |  Branch (226:38): [True: 2.28k, False: 2.28k]
  ------------------
  227|  2.28k|                pOut[a] = static_cast<int>(reinterpret_cast<int32_t *>(prop->mData)[a]);
  228|  2.28k|            }
  229|  2.28k|        }
  230|  2.28k|        if (pMax) {
  ------------------
  |  Branch (230:13): [True: 0, False: 2.28k]
  ------------------
  231|      0|            *pMax = iWrite;
  232|      0|        }
  233|  2.28k|    }
  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.28k|    return AI_SUCCESS;
  274|  2.28k|}
_ZN10aiMaterialC2Ev:
  418|  3.17k|aiMaterial::aiMaterial() : mProperties(nullptr), mNumProperties(0), mNumAllocated(DefaultNumAllocated) {
  419|       |    // Allocate 5 entries by default
  420|  3.17k|    mProperties = new aiMaterialProperty *[DefaultNumAllocated];
  421|  3.17k|}
_ZN10aiMaterialD2Ev:
  424|  3.17k|aiMaterial::~aiMaterial() {
  425|  3.17k|    Clear();
  426|       |
  427|  3.17k|    delete[] mProperties;
  428|  3.17k|}
_ZN10aiMaterial5ClearEv:
  439|  3.17k|void aiMaterial::Clear() {
  440|  39.1k|    for (unsigned int i = 0; i < mNumProperties; ++i) {
  ------------------
  |  Branch (440:30): [True: 35.9k, False: 3.17k]
  ------------------
  441|       |        // delete this entry
  442|  35.9k|        delete mProperties[i];
  443|  35.9k|        AI_DEBUG_INVALIDATE_PTR(mProperties[i]);
  444|  35.9k|    }
  445|  3.17k|    mNumProperties = 0;
  446|       |
  447|       |    // The array remains allocated, we just invalidated its contents
  448|  3.17k|}
_ZN10aiMaterial17AddBinaryPropertyEPKvjPKcjj18aiPropertyTypeInfo:
  480|  35.9k|        aiPropertyTypeInfo pType) {
  481|  35.9k|    ai_assert(pInput != nullptr);
  482|  35.9k|    ai_assert(pKey != nullptr);
  483|  35.9k|    ai_assert(0 != pSizeInBytes);
  484|       |
  485|  35.9k|    if (0 == pSizeInBytes) {
  ------------------
  |  Branch (485:9): [True: 0, False: 35.9k]
  ------------------
  486|      0|        return AI_FAILURE;
  487|      0|    }
  488|       |
  489|       |    // first search the list whether there is already an entry with this key
  490|  35.9k|    unsigned int iOutIndex(UINT_MAX);
  491|   231k|    for (unsigned int i = 0; i < mNumProperties; ++i) {
  ------------------
  |  Branch (491:30): [True: 195k, False: 35.9k]
  ------------------
  492|   195k|        aiMaterialProperty *prop(mProperties[i]);
  493|       |
  494|   195k|        if (prop /* just for safety */ && !strcmp(prop->mKey.data, pKey) &&
  ------------------
  |  Branch (494:13): [True: 195k, False: 0]
  |  Branch (494:43): [True: 324, False: 195k]
  ------------------
  495|    324|                prop->mSemantic == type && prop->mIndex == index) {
  ------------------
  |  Branch (495:17): [True: 0, False: 324]
  |  Branch (495:44): [True: 0, False: 0]
  ------------------
  496|       |
  497|      0|            delete mProperties[i];
  498|      0|            iOutIndex = i;
  499|      0|        }
  500|   195k|    }
  501|       |
  502|       |    // Allocate a new material property
  503|  35.9k|    auto pcNew = std::make_unique<aiMaterialProperty>();
  504|       |
  505|       |    // .. and fill it
  506|  35.9k|    pcNew->mType = pType;
  507|  35.9k|    pcNew->mSemantic = type;
  508|  35.9k|    pcNew->mIndex = index;
  509|       |
  510|  35.9k|    pcNew->mDataLength = pSizeInBytes;
  511|  35.9k|    pcNew->mData = new char[pSizeInBytes];
  512|  35.9k|    memcpy(pcNew->mData, pInput, pSizeInBytes);
  513|       |
  514|  35.9k|    pcNew->mKey.length = static_cast<ai_uint32>(::strlen(pKey));
  515|  35.9k|    ai_assert(AI_MAXLEN > pcNew->mKey.length);
  516|  35.9k|    strcpy(pcNew->mKey.data, pKey);
  517|       |
  518|  35.9k|    if (UINT_MAX != iOutIndex) {
  ------------------
  |  Branch (518:9): [True: 0, False: 35.9k]
  ------------------
  519|      0|        mProperties[iOutIndex] = pcNew.release();
  520|      0|        return AI_SUCCESS;
  521|      0|    }
  522|       |
  523|       |    // resize the array ... double the storage allocated
  524|  35.9k|    if (mNumProperties == mNumAllocated) {
  ------------------
  |  Branch (524:9): [True: 6.23k, False: 29.6k]
  ------------------
  525|  6.23k|        const unsigned int iOld = mNumAllocated;
  526|  6.23k|        mNumAllocated *= 2;
  527|       |
  528|  6.23k|        aiMaterialProperty **ppTemp;
  529|  6.23k|        try {
  530|  6.23k|            ppTemp = new aiMaterialProperty *[mNumAllocated];
  531|  6.23k|        } catch (std::bad_alloc &) {
  532|      0|            return AI_OUTOFMEMORY;
  533|      0|        }
  534|       |
  535|       |        // just copy all items over; then replace the old array
  536|  6.23k|        memcpy(ppTemp, mProperties, iOld * sizeof(void *));
  537|       |
  538|  6.23k|        delete[] mProperties;
  539|  6.23k|        mProperties = ppTemp;
  540|  6.23k|    }
  541|       |    // push back ...
  542|  35.9k|    mProperties[mNumProperties++] = pcNew.release();
  543|       |
  544|       |    return AI_SUCCESS;
  545|  35.9k|}
_ZN10aiMaterial11AddPropertyEPK8aiStringPKcjj:
  551|  4.60k|        unsigned int index) {
  552|       |    ai_assert(sizeof(ai_uint32) == 4);
  553|  4.60k|    return AddBinaryProperty(pInput,
  554|  4.60k|            static_cast<unsigned int>(pInput->length + 1 + 4),
  555|  4.60k|            pKey,
  556|  4.60k|            type,
  557|  4.60k|            index,
  558|  4.60k|            aiPTI_String);
  559|  4.60k|}
_ZN6Assimp19ComputeMaterialHashEPK10aiMaterialb:
  562|  1.17k|uint32_t Assimp::ComputeMaterialHash(const aiMaterial *mat, bool includeMatName /*= false*/) {
  563|  1.17k|    uint32_t hash = 1503; // magic start value, chosen to be my birthday :-)
  564|  15.4k|    for (unsigned int i = 0; i < mat->mNumProperties; ++i) {
  ------------------
  |  Branch (564:30): [True: 14.2k, False: 1.17k]
  ------------------
  565|       |        // Exclude all properties whose first character is '?' from the hash
  566|       |        // See doc for aiMaterialProperty.
  567|  14.2k|        const aiMaterialProperty *prop = mat->mProperties[i];
  568|  14.2k|        if (nullptr != prop && (includeMatName || prop->mKey.data[0] != '?')) {
  ------------------
  |  Branch (568:13): [True: 14.2k, False: 0]
  |  Branch (568:33): [True: 0, False: 14.2k]
  |  Branch (568:51): [True: 13.3k, False: 922]
  ------------------
  569|       |
  570|  13.3k|            hash = SuperFastHash(prop->mKey.data, (unsigned int)prop->mKey.length, hash);
  571|  13.3k|            hash = SuperFastHash(prop->mData, prop->mDataLength, hash);
  572|       |
  573|       |            // Combine the semantic and the index with the hash
  574|  13.3k|            hash = SuperFastHash((const char *)&prop->mSemantic, sizeof(unsigned int), hash);
  575|  13.3k|            hash = SuperFastHash((const char *)&prop->mIndex, sizeof(unsigned int), hash);
  576|  13.3k|        }
  577|  14.2k|    }
  578|  1.17k|    return hash;
  579|  1.17k|}
MaterialSystem.cpp:_ZN12_GLOBAL__N_121GetMaterialFloatArrayIfEE8aiReturnPK10aiMaterialPKcjjPT_Pj:
   97|  2.28k|        unsigned int *pMax) {
   98|  2.28k|    ai_assert(pOut != nullptr);
   99|  2.28k|    ai_assert(pMat != nullptr);
  100|       |
  101|  2.28k|    const aiMaterialProperty *prop{nullptr};
  102|  2.28k|    aiGetMaterialProperty(pMat, pKey, type, index, &prop);
  103|  2.28k|    if (nullptr == prop) {
  ------------------
  |  Branch (103:9): [True: 0, False: 2.28k]
  ------------------
  104|      0|        return AI_FAILURE;
  105|      0|    }
  106|       |
  107|       |    // data is given in floats, convert to TReal
  108|  2.28k|    unsigned int iWrite = 0;
  109|  2.28k|    if (aiPTI_Float == prop->mType || aiPTI_Buffer == prop->mType) {
  ------------------
  |  Branch (109:9): [True: 2.28k, False: 0]
  |  Branch (109:39): [True: 0, False: 0]
  ------------------
  110|  2.28k|        iWrite = prop->mDataLength / sizeof(float);
  111|  2.28k|        if (pMax) {
  ------------------
  |  Branch (111:13): [True: 0, False: 2.28k]
  ------------------
  112|      0|            iWrite = std::min(*pMax, iWrite);
  113|      0|        }
  114|       |
  115|  4.57k|        for (unsigned int a = 0; a < iWrite; ++a) {
  ------------------
  |  Branch (115:34): [True: 2.28k, False: 2.28k]
  ------------------
  116|  2.28k|            pOut[a] = static_cast<TReal>(reinterpret_cast<float *>(prop->mData)[a]);
  117|  2.28k|        }
  118|       |
  119|  2.28k|        if (pMax) {
  ------------------
  |  Branch (119:13): [True: 0, False: 2.28k]
  ------------------
  120|      0|            *pMax = iWrite;
  121|      0|        }
  122|  2.28k|    } 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.28k|    return AI_SUCCESS;
  172|  2.28k|}

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

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

_ZN6Assimp19CalcTangentsProcessC2Ev:
   59|  3.24k|        configMaxAngle(float(AI_DEG_TO_RAD(45.f))), configSourceUV(0) {
   60|       |    // nothing to do here
   61|  3.24k|}
_ZNK6Assimp19CalcTangentsProcess8IsActiveEj:
   65|  1.27k|bool CalcTangentsProcess::IsActive(unsigned int pFlags) const {
   66|  1.27k|    return (pFlags & aiProcess_CalcTangentSpace) != 0;
   67|  1.27k|}
_ZN6Assimp19CalcTangentsProcess15SetupPropertiesEPKNS_8ImporterE:
   71|  1.27k|void CalcTangentsProcess::SetupProperties(const Importer *pImp) {
   72|  1.27k|    ai_assert(nullptr != pImp);
   73|       |
   74|       |    // get the current value of the property
   75|  1.27k|    configMaxAngle = pImp->GetPropertyFloat(AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE, 45.f);
   76|  1.27k|    configMaxAngle = std::max(std::min(configMaxAngle, 45.0f), 0.0f);
   77|  1.27k|    configMaxAngle = AI_DEG_TO_RAD(configMaxAngle);
   78|       |
   79|       |    configSourceUV = pImp->GetPropertyInteger(AI_CONFIG_PP_CT_TEXTURE_CHANNEL_INDEX, 0);
   80|  1.27k|}
_ZN6Assimp19CalcTangentsProcess7ExecuteEP7aiScene:
   84|  1.27k|void CalcTangentsProcess::Execute(aiScene *pScene) {
   85|  1.27k|    ai_assert(nullptr != pScene);
   86|       |
   87|  1.27k|    ASSIMP_LOG_DEBUG("CalcTangentsProcess begin");
   88|       |
   89|  1.27k|    bool bHas = false;
   90|  3.16k|    for (unsigned int a = 0; a < pScene->mNumMeshes; a++) {
  ------------------
  |  Branch (90:30): [True: 1.89k, False: 1.27k]
  ------------------
   91|  1.89k|        if (ProcessMesh(pScene->mMeshes[a], a)) bHas = true;
  ------------------
  |  Branch (91:13): [True: 231, False: 1.66k]
  ------------------
   92|  1.89k|    }
   93|       |
   94|  1.27k|    if (bHas) {
  ------------------
  |  Branch (94:9): [True: 231, False: 1.04k]
  ------------------
   95|    231|        ASSIMP_LOG_INFO("CalcTangentsProcess finished. Tangents have been calculated");
   96|  1.04k|    } else {
   97|       |        ASSIMP_LOG_DEBUG("CalcTangentsProcess finished");
   98|  1.04k|    }
   99|  1.27k|}
_ZN6Assimp19CalcTangentsProcess11ProcessMeshEP6aiMeshj:
  103|  1.89k|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|  1.89k|    if (pMesh->mTangents) // this implies that mBitangents is also there
  ------------------
  |  Branch (109:9): [True: 33, False: 1.85k]
  ------------------
  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|  1.85k|    if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON))) {
  ------------------
  |  Branch (115:9): [True: 1.13k, False: 722]
  ------------------
  116|  1.13k|        ASSIMP_LOG_INFO("Tangents are undefined for line and point meshes");
  117|  1.13k|        return false;
  118|  1.13k|    }
  119|       |
  120|       |    // what we can check, though, is if the mesh has normals and texture coordinates. That's a requirement
  121|    722|    if (pMesh->mNormals == nullptr) {
  ------------------
  |  Branch (121:9): [True: 0, False: 722]
  ------------------
  122|      0|        ASSIMP_LOG_ERROR("Failed to compute tangents; need normals");
  123|      0|        return false;
  124|      0|    }
  125|    722|    if (configSourceUV >= AI_MAX_NUMBER_OF_TEXTURECOORDS || !pMesh->mTextureCoords[configSourceUV]) {
  ------------------
  |  Branch (125:9): [True: 0, False: 722]
  |  Branch (125:61): [True: 491, False: 231]
  ------------------
  126|    491|        ASSIMP_LOG_ERROR("Failed to compute tangents; need UV data in channel", configSourceUV);
  127|    491|        return false;
  128|    491|    }
  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|  1.63k|    for (unsigned int a = 0; a < pMesh->mNumFaces; a++) {
  ------------------
  |  Branch (146:30): [True: 1.39k, False: 231]
  ------------------
  147|  1.39k|        const aiFace &face = pMesh->mFaces[a];
  148|  1.39k|        if (face.mNumIndices < 3) {
  ------------------
  |  Branch (148:13): [True: 0, False: 1.39k]
  ------------------
  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.39k|        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.39k|        aiVector3D v = meshPos[p1] - meshPos[p0], w = meshPos[p2] - meshPos[p0];
  169|       |
  170|       |        // texture offset p1->p2 and p1->p3
  171|  1.39k|        float sx = meshTex[p1].x - meshTex[p0].x, sy = meshTex[p1].y - meshTex[p0].y;
  172|  1.39k|        float tx = meshTex[p2].x - meshTex[p0].x, ty = meshTex[p2].y - meshTex[p0].y;
  173|  1.39k|        float dirCorrection = (tx * sy - ty * sx) < 0.0f ? -1.0f : 1.0f;
  ------------------
  |  Branch (173:31): [True: 380, False: 1.01k]
  ------------------
  174|       |        // when t1, t2, t3 in same position in UV space, just use default UV direction.
  175|  1.39k|        if (sx * ty == sy * tx) {
  ------------------
  |  Branch (175:13): [True: 686, False: 713]
  ------------------
  176|    686|            sx = 0.0;
  177|    686|            sy = 1.0;
  178|    686|            tx = 1.0;
  179|    686|            ty = 0.0;
  180|    686|        }
  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.39k|        aiVector3D tangent, bitangent;
  185|  1.39k|        tangent.x = (w.x * sy - v.x * ty) * dirCorrection;
  186|  1.39k|        tangent.y = (w.y * sy - v.y * ty) * dirCorrection;
  187|  1.39k|        tangent.z = (w.z * sy - v.z * ty) * dirCorrection;
  188|  1.39k|        bitangent.x = (w.x * sx - v.x * tx) * dirCorrection;
  189|  1.39k|        bitangent.y = (w.y * sx - v.y * tx) * dirCorrection;
  190|  1.39k|        bitangent.z = (w.z * sx - v.z * tx) * dirCorrection;
  191|       |
  192|       |        // store for every vertex of that face
  193|  5.59k|        for (unsigned int b = 0; b < face.mNumIndices; ++b) {
  ------------------
  |  Branch (193:34): [True: 4.19k, False: 1.39k]
  ------------------
  194|  4.19k|            unsigned int p = face.mIndices[b];
  195|       |
  196|       |            // project tangent and bitangent into the plane formed by the vertex' normal
  197|  4.19k|            aiVector3D localTangent = tangent - meshNorm[p] * (tangent * meshNorm[p]);
  198|  4.19k|            aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]);
  199|  4.19k|            localTangent.NormalizeSafe();
  200|  4.19k|            localBitangent.NormalizeSafe();
  201|       |
  202|       |            // reconstruct tangent/bitangent according to normal and bitangent/tangent when it's infinite or NaN.
  203|  4.19k|            bool invalid_tangent = is_special_float(localTangent.x) || is_special_float(localTangent.y) || is_special_float(localTangent.z)
  ------------------
  |  Branch (203:36): [True: 891, False: 3.30k]
  |  Branch (203:72): [True: 98, False: 3.20k]
  |  Branch (203:108): [True: 37, False: 3.17k]
  ------------------
  204|  3.17k|                || (-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: 2.81k, False: 353]
  |  Branch (204:47): [True: 2.03k, False: 782]
  |  Branch (204:72): [True: 1.79k, False: 238]
  |  Branch (204:98): [True: 1.52k, False: 277]
  |  Branch (204:123): [True: 1.38k, False: 134]
  |  Branch (204:149): [True: 1.28k, False: 98]
  ------------------
  205|  4.19k|            bool invalid_bitangent = is_special_float(localBitangent.x) || is_special_float(localBitangent.y) || is_special_float(localBitangent.z)
  ------------------
  |  Branch (205:38): [True: 772, False: 3.42k]
  |  Branch (205:76): [True: 84, False: 3.34k]
  |  Branch (205:114): [True: 35, False: 3.30k]
  ------------------
  206|  3.30k|                || (-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: 2.94k, False: 359]
  |  Branch (206:49): [True: 2.61k, False: 335]
  |  Branch (206:76): [True: 2.10k, False: 509]
  |  Branch (206:104): [True: 1.66k, False: 441]
  |  Branch (206:131): [True: 1.50k, False: 155]
  |  Branch (206:159): [True: 1.41k, False: 95]
  ------------------
  207|  4.19k|            if (invalid_tangent != invalid_bitangent) {
  ------------------
  |  Branch (207:17): [True: 970, False: 3.22k]
  ------------------
  208|    970|                if (invalid_tangent) {
  ------------------
  |  Branch (208:21): [True: 491, False: 479]
  ------------------
  209|    491|                    localTangent = meshNorm[p] ^ localBitangent;
  210|    491|                    localTangent.NormalizeSafe();
  211|    491|                } else {
  212|    479|                    localBitangent = localTangent ^ meshNorm[p];
  213|    479|                    localBitangent.NormalizeSafe();
  214|    479|                }
  215|    970|            }
  216|       |
  217|       |            // and write it into the mesh.
  218|  4.19k|            meshTang[p] = localTangent;
  219|  4.19k|            meshBitang[p] = localBitangent;
  220|  4.19k|        }
  221|  1.39k|    }
  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|  4.06k|    for (unsigned int a = 0; a < pMesh->mNumVertices; a++) {
  ------------------
  |  Branch (250:30): [True: 3.83k, False: 231]
  ------------------
  251|  3.83k|        if (vertexDone[a])
  ------------------
  |  Branch (251:13): [True: 1.17k, False: 2.65k]
  ------------------
  252|  1.17k|            continue;
  253|       |
  254|  2.65k|        const aiVector3D &origPos = pMesh->mVertices[a];
  255|  2.65k|        const aiVector3D &origNorm = pMesh->mNormals[a];
  256|  2.65k|        const aiVector3D &origTang = pMesh->mTangents[a];
  257|  2.65k|        const aiVector3D &origBitang = pMesh->mBitangents[a];
  258|  2.65k|        closeVertices.resize(0);
  259|       |
  260|       |        // find all vertices close to that position
  261|  2.65k|        vertexFinder->FindPositions(origPos, posEpsilon, verticesFound);
  262|       |
  263|  2.65k|        closeVertices.reserve(verticesFound.size() + 5);
  264|  2.65k|        closeVertices.push_back(a);
  265|       |
  266|       |        // look among them for other vertices sharing the same normal and a close-enough tangent/bitangent
  267|  32.0k|        for (unsigned int b = 0; b < verticesFound.size(); b++) {
  ------------------
  |  Branch (267:34): [True: 29.3k, False: 2.65k]
  ------------------
  268|  29.3k|            unsigned int idx = verticesFound[b];
  269|  29.3k|            if (vertexDone[idx])
  ------------------
  |  Branch (269:17): [True: 3.57k, False: 25.7k]
  ------------------
  270|  3.57k|                continue;
  271|  25.7k|            if (meshNorm[idx] * origNorm < angleEpsilon)
  ------------------
  |  Branch (271:17): [True: 21.0k, False: 4.76k]
  ------------------
  272|  21.0k|                continue;
  273|  4.76k|            if (meshTang[idx] * origTang < fLimit)
  ------------------
  |  Branch (273:17): [True: 2.35k, False: 2.40k]
  ------------------
  274|  2.35k|                continue;
  275|  2.40k|            if (meshBitang[idx] * origBitang < fLimit)
  ------------------
  |  Branch (275:17): [True: 441, False: 1.96k]
  ------------------
  276|    441|                continue;
  277|       |
  278|       |            // it's similar enough -> add it to the smoothing group
  279|  1.96k|            closeVertices.push_back(idx);
  280|  1.96k|            vertexDone[idx] = true;
  281|  1.96k|        }
  282|       |
  283|       |        // smooth the tangents and bitangents of all vertices that were found to be close enough
  284|  2.65k|        aiVector3D smoothTangent(0, 0, 0), smoothBitangent(0, 0, 0);
  285|  7.27k|        for (unsigned int b = 0; b < closeVertices.size(); ++b) {
  ------------------
  |  Branch (285:34): [True: 4.62k, False: 2.65k]
  ------------------
  286|  4.62k|            smoothTangent += meshTang[closeVertices[b]];
  287|  4.62k|            smoothBitangent += meshBitang[closeVertices[b]];
  288|  4.62k|        }
  289|  2.65k|        smoothTangent.Normalize();
  290|  2.65k|        smoothBitangent.Normalize();
  291|       |
  292|       |        // and write it back into all affected tangents
  293|  7.27k|        for (unsigned int b = 0; b < closeVertices.size(); ++b) {
  ------------------
  |  Branch (293:34): [True: 4.62k, False: 2.65k]
  ------------------
  294|  4.62k|            meshTang[closeVertices[b]] = smoothTangent;
  295|  4.62k|            meshBitang[closeVertices[b]] = smoothBitangent;
  296|  4.62k|        }
  297|  2.65k|    }
  298|    231|    return true;
  299|    722|}

_ZNK6Assimp23ComputeUVMappingProcess8IsActiveEj:
   61|  1.32k|bool ComputeUVMappingProcess::IsActive(unsigned int pFlags) const {
   62|  1.32k|    return (pFlags & aiProcess_GenUVCoords) != 0;
   63|  1.32k|}
_ZN6Assimp23ComputeUVMappingProcess7ExecuteEP7aiScene:
  345|  1.32k|void ComputeUVMappingProcess::Execute(aiScene *pScene) {
  346|  1.32k|    ASSIMP_LOG_DEBUG("GenUVCoordsProcess begin");
  347|  1.32k|    char buffer[1024];
  348|       |
  349|  1.32k|    if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
  ------------------
  |  Branch (349:9): [True: 0, False: 1.32k]
  ------------------
  350|      0|        throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
  351|      0|    }
  352|       |
  353|  1.32k|    std::list<MappingInfo> mappingStack;
  354|       |
  355|       |    // Iterate through all materials and search for non-UV mapped textures
  356|  2.50k|    for (unsigned int i = 0; i < pScene->mNumMaterials; ++i) {
  ------------------
  |  Branch (356:30): [True: 1.17k, False: 1.32k]
  ------------------
  357|  1.17k|        mappingStack.clear();
  358|  1.17k|        aiMaterial *mat = pScene->mMaterials[i];
  359|  1.17k|        if (mat == nullptr) {
  ------------------
  |  Branch (359:13): [True: 0, False: 1.17k]
  ------------------
  360|      0|            ASSIMP_LOG_INFO("Material pointer in nullptr, skipping.");
  361|      0|            continue;
  362|      0|        }
  363|  15.4k|        for (unsigned int a = 0; a < mat->mNumProperties; ++a) {
  ------------------
  |  Branch (363:34): [True: 14.2k, False: 1.17k]
  ------------------
  364|  14.2k|            aiMaterialProperty *prop = mat->mProperties[a];
  365|  14.2k|            if (!::strcmp(prop->mKey.data, "$tex.mapping")) {
  ------------------
  |  Branch (365:17): [True: 0, False: 14.2k]
  ------------------
  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|  14.2k|        }
  448|  1.17k|    }
  449|  1.32k|    ASSIMP_LOG_DEBUG("GenUVCoordsProcess finished");
  450|  1.32k|}

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

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

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

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

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

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

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

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

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

_ZN6Assimp22FindDegeneratesProcessC2Ev:
   62|  3.24k|        mConfigRemoveDegenerates(false),
   63|  3.24k|        mConfigCheckAreaOfTriangle(false) {
   64|       |    // empty
   65|  3.24k|}
_ZNK6Assimp22FindDegeneratesProcess8IsActiveEj:
   69|  1.32k|bool FindDegeneratesProcess::IsActive(unsigned int pFlags) const {
   70|  1.32k|    return 0 != (pFlags & aiProcess_FindDegenerates);
   71|  1.32k|}
_ZN6Assimp22FindDegeneratesProcess15SetupPropertiesEPKNS_8ImporterE:
   75|  1.32k|void FindDegeneratesProcess::SetupProperties(const Importer *pImp) {
   76|       |    // Get the current value of AI_CONFIG_PP_FD_REMOVE
   77|  1.32k|    mConfigRemoveDegenerates = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_REMOVE, 0));
   78|       |    mConfigCheckAreaOfTriangle = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_CHECKAREA));
   79|  1.32k|}
_ZN6Assimp22FindDegeneratesProcess7ExecuteEP7aiScene:
   83|  1.32k|void FindDegeneratesProcess::Execute(aiScene *pScene) {
   84|  1.32k|    ASSIMP_LOG_DEBUG("FindDegeneratesProcess begin");
   85|  1.32k|    if (nullptr == pScene) {
  ------------------
  |  Branch (85:9): [True: 0, False: 1.32k]
  ------------------
   86|      0|        return;
   87|      0|    }
   88|       |
   89|  1.32k|    std::unordered_map<unsigned int, unsigned int> meshMap;
   90|  1.32k|    meshMap.reserve(pScene->mNumMeshes);
   91|       |
   92|  1.32k|    const unsigned int originalNumMeshes = pScene->mNumMeshes;
   93|  1.32k|    unsigned int targetIndex = 0;
   94|  2.50k|    for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
  ------------------
  |  Branch (94:30): [True: 1.17k, False: 1.32k]
  ------------------
   95|       |        // Do not process point cloud, ExecuteOnMesh works only with faces data
   96|  1.17k|        if ((pScene->mMeshes[i]->mPrimitiveTypes != aiPrimitiveType::aiPrimitiveType_POINT) && ExecuteOnMesh(pScene->mMeshes[i])) {
  ------------------
  |  Branch (96:13): [True: 1.13k, False: 41]
  |  Branch (96:96): [True: 0, False: 1.13k]
  ------------------
   97|      0|            delete pScene->mMeshes[i];
   98|       |            // Not strictly required, but clean:
   99|      0|            pScene->mMeshes[i] = nullptr;
  100|  1.17k|        } else {
  101|  1.17k|            meshMap[i] = targetIndex;
  102|  1.17k|            pScene->mMeshes[targetIndex] = pScene->mMeshes[i];
  103|  1.17k|            ++targetIndex;
  104|  1.17k|        }
  105|  1.17k|    }
  106|  1.32k|    pScene->mNumMeshes = targetIndex;
  107|       |
  108|  1.32k|    if (meshMap.size() < originalNumMeshes) {
  ------------------
  |  Branch (108:9): [True: 0, False: 1.32k]
  ------------------
  109|      0|        updateSceneGraph(pScene->mRootNode, meshMap);
  110|      0|    }
  111|       |
  112|       |    ASSIMP_LOG_DEBUG("FindDegeneratesProcess finished");
  113|  1.32k|}
_ZN6Assimp22FindDegeneratesProcess13ExecuteOnMeshEP6aiMesh:
  134|  1.13k|bool FindDegeneratesProcess::ExecuteOnMesh(aiMesh *mesh) {
  135|  1.13k|    mesh->mPrimitiveTypes = 0;
  136|       |
  137|  1.13k|    std::vector<bool> remove_me;
  138|  1.13k|    if (mConfigRemoveDegenerates) {
  ------------------
  |  Branch (138:9): [True: 0, False: 1.13k]
  ------------------
  139|      0|        remove_me.resize(mesh->mNumFaces, false);
  140|      0|    }
  141|       |
  142|  1.13k|    unsigned int deg = 0, limit;
  143|  25.7k|    for (unsigned int a = 0; a < mesh->mNumFaces; ++a) {
  ------------------
  |  Branch (143:30): [True: 24.6k, False: 1.13k]
  ------------------
  144|  24.6k|        aiFace &face = mesh->mFaces[a];
  145|  24.6k|        bool first = true;
  146|  24.6k|        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|  85.8k|        for (unsigned int i = 0; i < face.mNumIndices; ++i) {
  ------------------
  |  Branch (149:34): [True: 61.1k, False: 24.6k]
  ------------------
  150|  61.1k|            if (!std::all_of(face.mIndices, face.mIndices + face.mNumIndices, vertex_in_range))
  ------------------
  |  Branch (150:17): [True: 0, False: 61.1k]
  ------------------
  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|  61.1k|            limit = face.mNumIndices;
  157|  61.1k|            if (face.mNumIndices > 4) {
  ------------------
  |  Branch (157:17): [True: 0, False: 61.1k]
  ------------------
  158|      0|                limit = std::min(limit, i + 2);
  159|      0|            }
  160|       |
  161|   123k|            for (unsigned int t = i + 1; t < limit; ++t) {
  ------------------
  |  Branch (161:42): [True: 62.4k, False: 61.1k]
  ------------------
  162|  62.4k|                if (mesh->mVertices[face.mIndices[i]] == mesh->mVertices[face.mIndices[t]]) {
  ------------------
  |  Branch (162:21): [True: 9.06k, False: 53.3k]
  ------------------
  163|       |                    // we have found a matching vertex position
  164|       |                    // remove the corresponding index from the array
  165|  9.06k|                    --face.mNumIndices;
  166|  9.06k|                    --limit;
  167|  11.9k|                    for (unsigned int m = t; m < face.mNumIndices; ++m) {
  ------------------
  |  Branch (167:46): [True: 2.92k, False: 9.06k]
  ------------------
  168|  2.92k|                        face.mIndices[m] = face.mIndices[m + 1];
  169|  2.92k|                    }
  170|  9.06k|                    --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|  9.06k|                    face.mIndices[face.mNumIndices] = 0xdeadbeef;
  176|       |
  177|  9.06k|                    if (first) {
  ------------------
  |  Branch (177:25): [True: 7.02k, False: 2.04k]
  ------------------
  178|  7.02k|                        ++deg;
  179|  7.02k|                        first = false;
  180|  7.02k|                    }
  181|       |
  182|  9.06k|                    if (mConfigRemoveDegenerates) {
  ------------------
  |  Branch (182:25): [True: 0, False: 9.06k]
  ------------------
  183|      0|                        remove_me[a] = true;
  184|      0|                        goto evil_jump_outside; // hrhrhrh ... yeah, this rocks baby!
  185|      0|                    }
  186|  9.06k|                }
  187|  62.4k|            }
  188|       |
  189|  61.1k|            if (mConfigCheckAreaOfTriangle) {
  ------------------
  |  Branch (189:17): [True: 61.1k, False: 0]
  ------------------
  190|  61.1k|                if (face.mNumIndices == 3) {
  ------------------
  |  Branch (190:21): [True: 47.6k, False: 13.5k]
  ------------------
  191|  47.6k|                    ai_real area = GeometryUtils::calculateAreaOfTriangle(face, mesh);
  192|  47.6k|                    if (area < ai_epsilon) {
  ------------------
  |  Branch (192:25): [True: 39.9k, False: 7.66k]
  ------------------
  193|  39.9k|                        if (mConfigRemoveDegenerates) {
  ------------------
  |  Branch (193:29): [True: 0, False: 39.9k]
  ------------------
  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|  39.9k|                    }
  201|  47.6k|                }
  202|  61.1k|            }
  203|  61.1k|        }
  204|       |
  205|       |        // We need to update the primitive flags array of the mesh.
  206|  24.6k|        switch (face.mNumIndices) {
  207|  3.51k|        case 1u:
  ------------------
  |  Branch (207:9): [True: 3.51k, False: 21.1k]
  ------------------
  208|  3.51k|            mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
  209|  3.51k|            break;
  210|  5.73k|        case 2u:
  ------------------
  |  Branch (210:9): [True: 5.73k, False: 18.9k]
  ------------------
  211|  5.73k|            mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
  212|  5.73k|            break;
  213|  15.3k|        case 3u:
  ------------------
  |  Branch (213:9): [True: 15.3k, False: 9.25k]
  ------------------
  214|  15.3k|            mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
  215|  15.3k|            break;
  216|      0|        default:
  ------------------
  |  Branch (216:9): [True: 0, False: 24.6k]
  ------------------
  217|      0|            mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
  218|      0|            break;
  219|  24.6k|        };
  220|  24.6k|    evil_jump_outside:
  221|  24.6k|        continue;
  222|  24.6k|    }
  223|       |
  224|       |    // If AI_CONFIG_PP_FD_REMOVE is true, remove degenerated faces from the import
  225|  1.13k|    if (mConfigRemoveDegenerates && deg) {
  ------------------
  |  Branch (225:9): [True: 0, False: 1.13k]
  |  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.13k|    if (deg && !DefaultLogger::isNullLogger()) {
  ------------------
  |  Branch (258:9): [True: 943, False: 195]
  |  Branch (258:16): [True: 0, False: 943]
  ------------------
  259|       |        ASSIMP_LOG_WARN("Found ", deg, " degenerated primitives");
  260|      0|    }
  261|  1.13k|    return false;
  262|  1.13k|}
FindDegenerates.cpp:_ZZN6Assimp22FindDegeneratesProcess13ExecuteOnMeshEP6aiMeshENK3$_0clEj:
  146|   175k|        auto vertex_in_range = [numVertices = mesh->mNumVertices](unsigned int vertex_idx) { return vertex_idx < numVertices; };

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

_ZN6Assimp22FindInvalidDataProcessC2Ev:
   59|  3.24k|        configEpsilon(0.0), mIgnoreTexCoods(false) {
   60|       |    // nothing to do here
   61|  3.24k|}
_ZNK6Assimp22FindInvalidDataProcess8IsActiveEj:
   65|  1.32k|bool FindInvalidDataProcess::IsActive(unsigned int pFlags) const {
   66|  1.32k|    return 0 != (pFlags & aiProcess_FindInvalidData);
   67|  1.32k|}
_ZN6Assimp22FindInvalidDataProcess15SetupPropertiesEPKNS_8ImporterE:
   71|  1.32k|void FindInvalidDataProcess::SetupProperties(const Importer *pImp) {
   72|       |    // Get the current value of AI_CONFIG_PP_FID_ANIM_ACCURACY
   73|  1.32k|    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.32k|}
_Z20UpdateMeshReferencesP6aiNodeRKNSt3__16vectorIjNS1_9allocatorIjEEEE:
   79|  1.39k|void UpdateMeshReferences(aiNode *node, const std::vector<unsigned int> &meshMapping) {
   80|  1.39k|    if (node->mNumMeshes) {
  ------------------
  |  Branch (80:9): [True: 255, False: 1.13k]
  ------------------
   81|    255|        unsigned int out = 0;
   82|    879|        for (unsigned int a = 0; a < node->mNumMeshes; ++a) {
  ------------------
  |  Branch (82:34): [True: 624, False: 255]
  ------------------
   83|       |
   84|    624|            unsigned int ref = node->mMeshes[a];
   85|    624|            if (ref >= meshMapping.size())
  ------------------
  |  Branch (85:17): [True: 0, False: 624]
  ------------------
   86|      0|                throw DeadlyImportError("Invalid mesh ref");
   87|       |
   88|    624|            if (UINT_MAX != (ref = meshMapping[ref])) {
  ------------------
  |  Branch (88:17): [True: 366, False: 258]
  ------------------
   89|    366|                node->mMeshes[out++] = ref;
   90|    366|            }
   91|    624|        }
   92|       |        // just let the members that are unused, that's much cheaper
   93|       |        // than a full array realloc'n'copy party ...
   94|    255|        node->mNumMeshes = out;
   95|    255|        if (0 == out) {
  ------------------
  |  Branch (95:13): [True: 0, False: 255]
  ------------------
   96|      0|            delete[] node->mMeshes;
   97|      0|            node->mMeshes = nullptr;
   98|      0|        }
   99|    255|    }
  100|       |    // recursively update all children
  101|  2.54k|    for (unsigned int i = 0; i < node->mNumChildren; ++i) {
  ------------------
  |  Branch (101:30): [True: 1.15k, False: 1.39k]
  ------------------
  102|  1.15k|        UpdateMeshReferences(node->mChildren[i], meshMapping);
  103|  1.15k|    }
  104|  1.39k|}
_ZN6Assimp22FindInvalidDataProcess7ExecuteEP7aiScene:
  108|  1.32k|void FindInvalidDataProcess::Execute(aiScene *pScene) {
  109|  1.32k|    ASSIMP_LOG_DEBUG("FindInvalidDataProcess begin");
  110|       |
  111|  1.32k|    bool out = false;
  112|  1.32k|    std::vector<unsigned int> meshMapping(pScene->mNumMeshes);
  113|  1.32k|    unsigned int real = 0;
  114|       |
  115|       |    // Process meshes
  116|  3.53k|    for (unsigned int a = 0; a < pScene->mNumMeshes; a++) {
  ------------------
  |  Branch (116:30): [True: 2.20k, False: 1.32k]
  ------------------
  117|  2.20k|        int result = ProcessMesh(pScene->mMeshes[a]);
  118|  2.20k|        if (0 == result) {
  ------------------
  |  Branch (118:13): [True: 1.61k, False: 590]
  ------------------
  119|  1.61k|            out = true;
  120|  1.61k|        }
  121|  2.20k|        if (2 == result) {
  ------------------
  |  Branch (121:13): [True: 316, False: 1.89k]
  ------------------
  122|       |            // remove this mesh
  123|    316|            delete pScene->mMeshes[a];
  124|    316|            pScene->mMeshes[a] = nullptr;
  125|       |
  126|    316|            meshMapping[a] = UINT_MAX;
  127|    316|            out = true;
  128|    316|            continue;
  129|    316|        }
  130|       |
  131|  1.89k|        pScene->mMeshes[real] = pScene->mMeshes[a];
  132|  1.89k|        meshMapping[a] = real++;
  133|  1.89k|    }
  134|       |
  135|       |    // Process animations
  136|  1.32k|    for (unsigned int animIdx = 0; animIdx < pScene->mNumAnimations; ++animIdx) {
  ------------------
  |  Branch (136:36): [True: 0, False: 1.32k]
  ------------------
  137|      0|        ProcessAnimation(pScene->mAnimations[animIdx]);
  138|      0|    }
  139|       |
  140|  1.32k|    if (out) {
  ------------------
  |  Branch (140:9): [True: 1.12k, False: 197]
  ------------------
  141|  1.12k|        if (real != pScene->mNumMeshes) {
  ------------------
  |  Branch (141:13): [True: 282, False: 845]
  ------------------
  142|    282|            if (!real) {
  ------------------
  |  Branch (142:17): [True: 49, False: 233]
  ------------------
  143|     49|                throw DeadlyImportError("No meshes remaining");
  144|     49|            }
  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|    233|            try {
  150|    233|                UpdateMeshReferences(pScene->mRootNode, meshMapping);
  151|    233|            } 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|    233|            pScene->mNumMeshes = real;
  157|    233|        }
  158|       |
  159|  1.12k|        ASSIMP_LOG_INFO("FindInvalidDataProcess finished. Found issues ...");
  160|  1.07k|    } else {
  161|       |        ASSIMP_LOG_DEBUG("FindInvalidDataProcess finished. Everything seems to be OK.");
  162|    197|    }
  163|  1.32k|}
_ZN6Assimp22FindInvalidDataProcess11ProcessMeshEP6aiMesh:
  323|  2.20k|int FindInvalidDataProcess::ProcessMesh(aiMesh *pMesh) {
  324|  2.20k|    bool ret = false;
  325|  2.20k|    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|  27.5k|    for (unsigned int m = 0; m < pMesh->mNumFaces; ++m) {
  ------------------
  |  Branch (329:30): [True: 25.3k, False: 2.20k]
  ------------------
  330|  25.3k|        const aiFace &f = pMesh->mFaces[m];
  331|       |
  332|  87.2k|        for (unsigned int i = 0; i < f.mNumIndices; ++i) {
  ------------------
  |  Branch (332:34): [True: 61.9k, False: 25.3k]
  ------------------
  333|  61.9k|            dirtyMask[f.mIndices[i]] = false;
  334|  61.9k|        }
  335|  25.3k|    }
  336|       |
  337|       |    // Process vertex positions
  338|  2.20k|    if (pMesh->mVertices && ProcessArray(pMesh->mVertices, pMesh->mNumVertices, "positions", dirtyMask)) {
  ------------------
  |  Branch (338:9): [True: 2.20k, False: 0]
  |  Branch (338:29): [True: 316, False: 1.89k]
  ------------------
  339|    316|        ASSIMP_LOG_ERROR("Deleting mesh: Unable to continue without vertex positions");
  340|       |
  341|    316|        return 2;
  342|    316|    }
  343|       |
  344|       |    // process texture coordinates
  345|  1.89k|    if (!mIgnoreTexCoods) {
  ------------------
  |  Branch (345:9): [True: 1.89k, False: 0]
  ------------------
  346|  2.46k|        for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS && pMesh->mTextureCoords[i]; ++i) {
  ------------------
  |  Branch (346:34): [True: 2.46k, False: 0]
  |  Branch (346:72): [True: 575, False: 1.89k]
  ------------------
  347|    575|            if (ProcessArray(pMesh->mTextureCoords[i], pMesh->mNumVertices, "uvcoords", dirtyMask)) {
  ------------------
  |  Branch (347:17): [True: 91, False: 484]
  ------------------
  348|     91|                pMesh->mNumUVComponents[i] = 0;
  349|       |
  350|       |                // delete all subsequent texture coordinate sets.
  351|    728|                for (unsigned int a = i + 1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
  ------------------
  |  Branch (351:46): [True: 637, False: 91]
  ------------------
  352|    637|                    delete[] pMesh->mTextureCoords[a];
  353|    637|                    pMesh->mTextureCoords[a] = nullptr;
  354|    637|                    pMesh->mNumUVComponents[a] = 0;
  355|    637|                }
  356|       |
  357|     91|                ret = true;
  358|     91|            }
  359|    575|        }
  360|  1.89k|    }
  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|  1.89k|    if (pMesh->mNormals || pMesh->mTangents) {
  ------------------
  |  Branch (366:9): [True: 1.16k, False: 729]
  |  Branch (366:28): [True: 0, False: 729]
  ------------------
  367|       |
  368|  1.16k|        if (aiPrimitiveType_POINT & pMesh->mPrimitiveTypes ||
  ------------------
  |  Branch (368:13): [True: 267, False: 896]
  ------------------
  369|    896|                aiPrimitiveType_LINE & pMesh->mPrimitiveTypes) {
  ------------------
  |  Branch (369:17): [True: 478, False: 418]
  ------------------
  370|    745|            if (aiPrimitiveType_TRIANGLE & pMesh->mPrimitiveTypes ||
  ------------------
  |  Branch (370:17): [True: 0, False: 745]
  ------------------
  371|    745|                    aiPrimitiveType_POLYGON & pMesh->mPrimitiveTypes) {
  ------------------
  |  Branch (371:21): [True: 0, False: 745]
  ------------------
  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|    745|            else {
  387|    745|                return ret;
  388|    745|            }
  389|    745|        }
  390|       |
  391|       |        // Process mesh normals
  392|    418|        if (pMesh->mNormals && ProcessArray(pMesh->mNormals, pMesh->mNumVertices,
  ------------------
  |  Branch (392:13): [True: 418, False: 0]
  |  Branch (392:32): [True: 187, False: 231]
  ------------------
  393|    418|                                       "normals", dirtyMask, true, false))
  394|    187|            ret = true;
  395|       |
  396|       |        // Process mesh tangents
  397|    418|        if (pMesh->mTangents && ProcessArray(pMesh->mTangents, pMesh->mNumVertices, "tangents", dirtyMask)) {
  ------------------
  |  Branch (397:13): [True: 19, False: 399]
  |  Branch (397:33): [True: 6, False: 13]
  ------------------
  398|      6|            delete[] pMesh->mBitangents;
  399|      6|            pMesh->mBitangents = nullptr;
  400|      6|            ret = true;
  401|      6|        }
  402|       |
  403|       |        // Process mesh bitangents
  404|    418|        if (pMesh->mBitangents && ProcessArray(pMesh->mBitangents, pMesh->mNumVertices, "bitangents", dirtyMask)) {
  ------------------
  |  Branch (404:13): [True: 13, False: 405]
  |  Branch (404:35): [True: 9, False: 4]
  ------------------
  405|      9|            delete[] pMesh->mTangents;
  406|      9|            pMesh->mTangents = nullptr;
  407|      9|            ret = true;
  408|      9|        }
  409|    418|    }
  410|  1.14k|    return ret ? 1 : 0;
  ------------------
  |  Branch (410:12): [True: 201, False: 946]
  ------------------
  411|  1.89k|}
_Z12ProcessArrayI10aiVector3tIfEEbRPT_jPKcRKNSt3__16vectorIbNS7_9allocatorIbEEEEbb:
  203|  3.23k|        const std::vector<bool> &dirtyMask, bool mayBeIdentical = false, bool mayBeZero = true) {
  204|  3.23k|    const char *err = ValidateArrayContents(in, num, dirtyMask, mayBeIdentical, mayBeZero);
  205|  3.23k|    if (err) {
  ------------------
  |  Branch (205:9): [True: 609, False: 2.62k]
  ------------------
  206|    609|        ASSIMP_LOG_ERROR("FindInvalidDataProcess fails on mesh ", name, ": ", err);
  207|    609|        delete[] in;
  208|    609|        in = nullptr;
  209|    609|        return true;
  210|    609|    }
  211|  2.62k|    return false;
  212|  3.23k|}
_Z21ValidateArrayContentsI10aiVector3tIfEEPKcPKT_jRKNSt3__16vectorIbNS7_9allocatorIbEEEEbb:
  175|  3.23k|        const std::vector<bool> &dirtyMask, bool mayBeIdentical, bool mayBeZero) {
  176|  3.23k|    bool b = false;
  177|  3.23k|    unsigned int cnt = 0;
  178|  71.2k|    for (unsigned int i = 0; i < size; ++i) {
  ------------------
  |  Branch (178:30): [True: 68.3k, False: 2.92k]
  ------------------
  179|       |
  180|  68.3k|        if (dirtyMask.size() && dirtyMask[i]) {
  ------------------
  |  Branch (180:13): [True: 68.3k, False: 0]
  |  Branch (180:13): [True: 581, False: 67.7k]
  |  Branch (180:33): [True: 581, False: 67.7k]
  ------------------
  181|    581|            continue;
  182|    581|        }
  183|  67.7k|        ++cnt;
  184|       |
  185|  67.7k|        const aiVector3D &v = arr[i];
  186|  67.7k|        if (is_special_float(v.x) || is_special_float(v.y) || is_special_float(v.z)) {
  ------------------
  |  Branch (186:13): [True: 81, False: 67.6k]
  |  Branch (186:38): [True: 32, False: 67.6k]
  |  Branch (186:63): [True: 26, False: 67.6k]
  ------------------
  187|    139|            return "INF/NAN was found in a vector component";
  188|    139|        }
  189|  67.6k|        if (!mayBeZero && !v.x && !v.y && !v.z) {
  ------------------
  |  Branch (189:13): [True: 4.39k, False: 63.2k]
  |  Branch (189:27): [True: 1.37k, False: 3.01k]
  |  Branch (189:35): [True: 877, False: 497]
  |  Branch (189:43): [True: 166, False: 711]
  ------------------
  190|    166|            return "Found zero-length vector";
  191|    166|        }
  192|  67.4k|        if (i && v != arr[i - 1]) b = true;
  ------------------
  |  Branch (192:13): [True: 64.4k, False: 3.02k]
  |  Branch (192:18): [True: 52.8k, False: 11.5k]
  ------------------
  193|  67.4k|    }
  194|  2.92k|    if (cnt > 1 && !b && !mayBeIdentical) {
  ------------------
  |  Branch (194:9): [True: 2.67k, False: 257]
  |  Branch (194:20): [True: 336, False: 2.33k]
  |  Branch (194:26): [True: 304, False: 32]
  ------------------
  195|    304|        return "All vectors are identical";
  196|    304|    }
  197|  2.62k|    return nullptr;
  198|  2.92k|}

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

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

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

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

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

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

_ZN6Assimp23GenVertexNormalsProcessC2Ev:
   57|  3.24k|        configMaxAngle(AI_DEG_TO_RAD(175.f)) {
   58|       |    // empty
   59|  3.24k|}
_ZNK6Assimp23GenVertexNormalsProcess8IsActiveEj:
   63|  1.27k|bool GenVertexNormalsProcess::IsActive(unsigned int pFlags) const {
   64|  1.27k|    force_ = (pFlags & aiProcess_ForceGenNormals) != 0;
   65|  1.27k|    flippedWindingOrder_ = (pFlags & aiProcess_FlipWindingOrder) != 0;
   66|  1.27k|    leftHanded_ = (pFlags & aiProcess_MakeLeftHanded) != 0;
   67|  1.27k|    return (pFlags & aiProcess_GenSmoothNormals) != 0;
   68|  1.27k|}
_ZN6Assimp23GenVertexNormalsProcess15SetupPropertiesEPKNS_8ImporterE:
   72|  1.27k|void GenVertexNormalsProcess::SetupProperties(const Importer *pImp) {
   73|       |    // Get the current value of the AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE property
   74|  1.27k|    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.27k|}
_ZN6Assimp23GenVertexNormalsProcess7ExecuteEP7aiScene:
   80|  1.27k|void GenVertexNormalsProcess::Execute(aiScene *pScene) {
   81|  1.27k|    ASSIMP_LOG_DEBUG("GenVertexNormalsProcess begin");
   82|       |
   83|  1.27k|    if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
  ------------------
  |  Branch (83:9): [True: 0, False: 1.27k]
  ------------------
   84|      0|        throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
   85|      0|    }
   86|       |
   87|  1.27k|    bool bHas = false;
   88|  3.16k|    for (unsigned int a = 0; a < pScene->mNumMeshes; ++a) {
  ------------------
  |  Branch (88:30): [True: 1.89k, False: 1.27k]
  ------------------
   89|  1.89k|        if (GenMeshVertexNormals(pScene->mMeshes[a], a))
  ------------------
  |  Branch (89:13): [True: 495, False: 1.39k]
  ------------------
   90|    495|            bHas = true;
   91|  1.89k|    }
   92|       |
   93|  1.27k|    if (bHas) {
  ------------------
  |  Branch (93:9): [True: 495, False: 780]
  ------------------
   94|    495|        ASSIMP_LOG_INFO("GenVertexNormalsProcess finished. "
   95|    495|                        "Vertex normals have been calculated");
   96|    780|    } else {
   97|       |        ASSIMP_LOG_DEBUG("GenVertexNormalsProcess finished. "
   98|    780|                         "Normals are already there");
   99|    780|    }
  100|  1.27k|}
_ZN6Assimp23GenVertexNormalsProcess20GenMeshVertexNormalsEP6aiMeshj:
  104|  1.89k|bool GenVertexNormalsProcess::GenMeshVertexNormals(aiMesh *pMesh, unsigned int meshIndex) {
  105|  1.89k|    if (nullptr != pMesh->mNormals) {
  ------------------
  |  Branch (105:9): [True: 976, False: 916]
  ------------------
  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|    916|    if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON))) {
  ------------------
  |  Branch (116:9): [True: 421, False: 495]
  ------------------
  117|    421|        ASSIMP_LOG_INFO("Normal vectors are undefined for line and point meshes");
  118|    421|        return false;
  119|    421|    }
  120|       |
  121|       |    // Allocate the array to hold the output normals
  122|    495|    const float qnan = std::numeric_limits<ai_real>::quiet_NaN();
  123|    495|    pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
  124|       |
  125|       |    // Compute per-face normals but store them per-vertex
  126|  14.5k|    for (unsigned int a = 0; a < pMesh->mNumFaces; a++) {
  ------------------
  |  Branch (126:30): [True: 14.0k, False: 495]
  ------------------
  127|  14.0k|        const aiFace &face = pMesh->mFaces[a];
  128|  14.0k|        if (face.mNumIndices < 3) {
  ------------------
  |  Branch (128:13): [True: 0, False: 14.0k]
  ------------------
  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|  14.0k|        const aiVector3D *pV1 = &pMesh->mVertices[face.mIndices[0]];
  138|  14.0k|        const aiVector3D *pV2 = &pMesh->mVertices[face.mIndices[1]];
  139|  14.0k|        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|  14.0k|        if (flippedWindingOrder_ != leftHanded_) {
  ------------------
  |  Branch (142:13): [True: 0, False: 14.0k]
  ------------------
  143|      0|            std::swap(pV2, pV3);
  144|      0|        }
  145|  14.0k|        const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe();
  146|       |
  147|  56.3k|        for (unsigned int i = 0; i < face.mNumIndices; ++i) {
  ------------------
  |  Branch (147:34): [True: 42.2k, False: 14.0k]
  ------------------
  148|  42.2k|            pMesh->mNormals[face.mIndices[i]] = vNor;
  149|  42.2k|        }
  150|  14.0k|    }
  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|    495|    SpatialSort *vertexFinder = nullptr;
  155|    495|    SpatialSort _vertexFinder;
  156|    495|    ai_real posEpsilon = ai_real(1e-5);
  157|    495|    if (shared) {
  ------------------
  |  Branch (157:9): [True: 495, False: 0]
  ------------------
  158|    495|        std::vector<std::pair<SpatialSort, ai_real>> *avf;
  159|    495|        shared->GetProperty(AI_SPP_SPATIAL_SORT, avf);
  ------------------
  |  |  166|    495|#define AI_SPP_SPATIAL_SORT "$Spat"
  ------------------
  160|    495|        if (avf) {
  ------------------
  |  Branch (160:13): [True: 495, False: 0]
  ------------------
  161|    495|            std::pair<SpatialSort, ai_real> &blubb = avf->operator[](meshIndex);
  162|    495|            vertexFinder = &blubb.first;
  163|    495|            posEpsilon = blubb.second;
  164|    495|        }
  165|    495|    }
  166|    495|    if (!vertexFinder) {
  ------------------
  |  Branch (166:9): [True: 0, False: 495]
  ------------------
  167|      0|        _vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof(aiVector3D));
  168|      0|        vertexFinder = &_vertexFinder;
  169|      0|        posEpsilon = ComputePositionEpsilon(pMesh);
  170|      0|    }
  171|    495|    std::vector<unsigned int> verticesFound;
  172|    495|    aiVector3D *pcNew = new aiVector3D[pMesh->mNumVertices];
  173|       |
  174|    495|    if (configMaxAngle >= AI_DEG_TO_RAD(175.f)) {
  ------------------
  |  Branch (174:9): [True: 495, 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|    495|        std::vector<bool> abHad(pMesh->mNumVertices, false);
  179|  40.9k|        for (unsigned int i = 0; i < pMesh->mNumVertices; ++i) {
  ------------------
  |  Branch (179:34): [True: 40.4k, False: 495]
  ------------------
  180|  40.4k|            if (abHad[i]) {
  ------------------
  |  Branch (180:17): [True: 4.65k, False: 35.7k]
  ------------------
  181|  4.65k|                continue;
  182|  4.65k|            }
  183|       |
  184|       |            // Get all vertices that share this one ...
  185|  35.7k|            vertexFinder->FindPositions(pMesh->mVertices[i], posEpsilon, verticesFound);
  186|       |
  187|  35.7k|            aiVector3D pcNor;
  188|  42.0k|            for (unsigned int a = 0; a < verticesFound.size(); ++a) {
  ------------------
  |  Branch (188:38): [True: 6.25k, False: 35.7k]
  ------------------
  189|  6.25k|                const aiVector3D &v = pMesh->mNormals[verticesFound[a]];
  190|  6.25k|                if (is_not_qnan(v.x)) pcNor += v;
  ------------------
  |  Branch (190:21): [True: 5.39k, False: 861]
  ------------------
  191|  6.25k|            }
  192|  35.7k|            pcNor.NormalizeSafe();
  193|       |
  194|       |            // Write the smoothed normal back to all affected normals
  195|  42.0k|            for (unsigned int a = 0; a < verticesFound.size(); ++a) {
  ------------------
  |  Branch (195:38): [True: 6.25k, False: 35.7k]
  ------------------
  196|  6.25k|                unsigned int vidx = verticesFound[a];
  197|  6.25k|                pcNew[vidx] = pcNor;
  198|  6.25k|                abHad[vidx] = true;
  199|  6.25k|            }
  200|  35.7k|        }
  201|    495|    }
  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|    495|    delete[] pMesh->mNormals;
  227|    495|    pMesh->mNormals = pcNew;
  228|       |
  229|    495|    return true;
  230|    916|}

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

_ZNK6Assimp19JoinVerticesProcess8IsActiveEj:
   63|  1.27k|bool JoinVerticesProcess::IsActive( unsigned int pFlags) const {
   64|  1.27k|    return (pFlags & aiProcess_JoinIdenticalVertices) != 0;
   65|  1.27k|}
_ZN6Assimp19JoinVerticesProcess7ExecuteEP7aiScene:
   68|  1.27k|void JoinVerticesProcess::Execute( aiScene* pScene) {
   69|  1.27k|    ASSIMP_LOG_DEBUG("JoinVerticesProcess begin");
   70|       |
   71|       |    // get the total number of vertices BEFORE the step is executed
   72|  1.27k|    int iNumOldVertices = 0;
   73|  1.27k|    if (!DefaultLogger::isNullLogger()) {
  ------------------
  |  Branch (73:9): [True: 0, False: 1.27k]
  ------------------
   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.27k|    int iNumVertices = 0;
   81|  3.16k|    for( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
  ------------------
  |  Branch (81:30): [True: 1.89k, False: 1.27k]
  ------------------
   82|  1.89k|        iNumVertices += ProcessMesh( pScene->mMeshes[a],a);
   83|  1.89k|    }
   84|       |
   85|  1.27k|    pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
   86|       |
   87|       |    // if logging is active, print detailed statistics
   88|  1.27k|    if (!DefaultLogger::isNullLogger()) {
  ------------------
  |  Branch (88:9): [True: 0, False: 1.27k]
  ------------------
   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.27k|}
_ZN6Assimp19JoinVerticesProcess11ProcessMeshEP6aiMeshj:
  225|  1.89k|int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) {
  226|  1.89k|    static_assert( AI_MAX_NUMBER_OF_COLOR_SETS    == 8, "AI_MAX_NUMBER_OF_COLOR_SETS    == 8");
  227|  1.89k|	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|  1.89k|    if (!pMesh->HasPositions() || !pMesh->HasFaces()) {
  ------------------
  |  Branch (230:9): [True: 0, False: 1.89k]
  |  Branch (230:35): [True: 0, False: 1.89k]
  ------------------
  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|  1.89k|    std::vector<bool> usedVertexIndicesMask;
  238|  1.89k|    usedVertexIndicesMask.resize(pMesh->mNumVertices, false);
  239|  24.9k|    for (unsigned int a = 0; a < pMesh->mNumFaces; a++) {
  ------------------
  |  Branch (239:30): [True: 23.0k, False: 1.89k]
  ------------------
  240|  23.0k|        aiFace& face = pMesh->mFaces[a];
  241|  82.1k|        for (unsigned int b = 0; b < face.mNumIndices; b++) {
  ------------------
  |  Branch (241:34): [True: 59.0k, False: 23.0k]
  ------------------
  242|  59.0k|            usedVertexIndicesMask[face.mIndices[b]] = true;
  243|  59.0k|        }
  244|  23.0k|    }
  245|       |
  246|       |    // We'll never have more vertices afterwards.
  247|  1.89k|    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|  1.89k|    static_assert(AI_MAX_VERTICES == 0x7fffffff, "AI_MAX_VERTICES == 0x7fffffff");
  255|  1.89k|    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|  1.89k|    const bool hasAnimMeshes = pMesh->mNumAnimMeshes > 0;
  260|       |
  261|       |    // We'll never have more vertices afterwards.
  262|  1.89k|    std::vector<std::vector<int>> uniqueAnimatedVertices;
  263|  1.89k|    if (hasAnimMeshes) {
  ------------------
  |  Branch (263:9): [True: 0, False: 1.89k]
  ------------------
  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|  1.89k|    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|  1.89k|    int newIndex = 0;
  274|  58.0k|    for( unsigned int a = 0; a < pMesh->mNumVertices; a++)  {
  ------------------
  |  Branch (274:30): [True: 56.1k, False: 1.89k]
  ------------------
  275|       |        // if the vertex is unused Do nothing
  276|  56.1k|        if (!usedVertexIndicesMask[a]) {
  ------------------
  |  Branch (276:13): [True: 315, False: 55.8k]
  ------------------
  277|    315|            continue;
  278|    315|        }
  279|       |        // collect the vertex data
  280|  55.8k|        Vertex v(pMesh,a);
  281|       |        // is the vertex already in the map?
  282|  55.8k|        auto it = vertex2Index.find(v);
  283|       |        // if the vertex is not in the map then it is a new vertex add it.
  284|  55.8k|        if (it == vertex2Index.end()) {
  ------------------
  |  Branch (284:13): [True: 18.9k, False: 36.8k]
  ------------------
  285|       |            // this is a new vertex give it a new index
  286|  18.9k|            vertex2Index.emplace(v, newIndex);
  287|       |            // keep track of its index and increment 1
  288|  18.9k|            replaceIndex[a] = newIndex++;
  289|       |            // add the vertex to the unique vertices
  290|  18.9k|            uniqueVertices.push_back(a);
  291|  18.9k|            if (hasAnimMeshes) {
  ------------------
  |  Branch (291:17): [True: 0, False: 18.9k]
  ------------------
  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|  36.8k|        } 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|  36.8k|            replaceIndex[a] = it->second | JOINED_VERTICES_MARK;
  300|  36.8k|        }
  301|  55.8k|    }
  302|       |
  303|  1.89k|    if (!DefaultLogger::isNullLogger() && DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE)    {
  ------------------
  |  Branch (303:9): [True: 0, False: 1.89k]
  |  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|  1.89k|    updateXMeshVertices(pMesh, uniqueVertices);
  318|  1.89k|    if (hasAnimMeshes) {
  ------------------
  |  Branch (318:9): [True: 0, False: 1.89k]
  ------------------
  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|  24.9k|    for( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
  ------------------
  |  Branch (325:30): [True: 23.0k, False: 1.89k]
  ------------------
  326|  23.0k|        aiFace& face = pMesh->mFaces[a];
  327|  82.1k|        for( unsigned int b = 0; b < face.mNumIndices; b++) {
  ------------------
  |  Branch (327:34): [True: 59.0k, False: 23.0k]
  ------------------
  328|  59.0k|            face.mIndices[b] = replaceIndex[face.mIndices[b]] & ~JOINED_VERTICES_MARK;
  329|  59.0k|        }
  330|  23.0k|    }
  331|       |
  332|       |    // adjust bone vertex weights.
  333|  4.25k|    for( int a = 0; a < (int)pMesh->mNumBones; a++) {
  ------------------
  |  Branch (333:21): [True: 2.36k, False: 1.89k]
  ------------------
  334|  2.36k|        aiBone* bone = pMesh->mBones[a];
  335|  2.36k|        std::vector<aiVertexWeight> newWeights;
  336|  2.36k|        newWeights.reserve( bone->mNumWeights);
  337|       |
  338|  2.36k|        if (nullptr != bone->mWeights) {
  ------------------
  |  Branch (338:13): [True: 2.36k, False: 0]
  ------------------
  339|  8.61k|            for ( unsigned int b = 0; b < bone->mNumWeights; b++ ) {
  ------------------
  |  Branch (339:39): [True: 6.25k, False: 2.36k]
  ------------------
  340|  6.25k|                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|  6.25k|                if ( !( replaceIndex[ ow.mVertexId ] & JOINED_VERTICES_MARK ) ) {
  ------------------
  |  Branch (343:22): [True: 5.43k, False: 812]
  ------------------
  344|  5.43k|                    aiVertexWeight nw;
  345|  5.43k|                    nw.mVertexId = replaceIndex[ ow.mVertexId ];
  346|  5.43k|                    nw.mWeight = ow.mWeight;
  347|  5.43k|                    newWeights.push_back( nw );
  348|  5.43k|                }
  349|  6.25k|            }
  350|  2.36k|        } else {
  351|      0|            ASSIMP_LOG_ERROR( "X-Export: aiBone shall contain weights, but pointer to them is nullptr." );
  352|      0|        }
  353|       |
  354|  2.36k|        if (newWeights.size() > 0) {
  ------------------
  |  Branch (354:13): [True: 2.28k, False: 81]
  ------------------
  355|       |            // kill the old and replace them with the translated weights
  356|  2.28k|            delete [] bone->mWeights;
  357|  2.28k|            bone->mNumWeights = (unsigned int)newWeights.size();
  358|       |
  359|  2.28k|            bone->mWeights = new aiVertexWeight[bone->mNumWeights];
  360|  2.28k|            memcpy( bone->mWeights, &newWeights[0], bone->mNumWeights * sizeof( aiVertexWeight));
  361|  2.28k|        }
  362|  2.36k|    }
  363|  1.89k|    return pMesh->mNumVertices;
  364|  1.89k|}
JoinVerticesProcess.cpp:_ZNK12_GLOBAL__N_110HashVertexclERKN6Assimp6VertexE:
  151|  72.9k|    size_t operator () (const Vertex & v) const {
  152|  72.9k|        size_t hash = 0;
  153|       |
  154|  72.9k|        hash_combine(hash, v.position.x);
  155|  72.9k|        hash_combine(hash, v.position.y);
  156|  72.9k|        hash_combine(hash, v.position.z);
  157|       |
  158|  72.9k|        return hash;
  159|  72.9k|    }
JoinVerticesProcess.cpp:_ZNK12_GLOBAL__N_110HashVertex12hash_combineERmRKf:
  146|   218k|    inline void hash_combine(std::size_t& seed, const ai_real& v) const {
  147|   218k|        std::hash<ai_real> hasher;
  148|   218k|        seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
  149|   218k|    }
JoinVerticesProcess.cpp:_ZNK12_GLOBAL__N_126CompareVerticesAlmostEqualclERKN6Assimp6VertexES4_:
  104|  41.2k|    bool operator () (const Vertex & a, const Vertex & b) const {
  105|  41.2k|        static const float epsilon = 1e-5f;
  106|  41.2k|        static const float squareEpsilon = epsilon * epsilon;
  107|       |
  108|  41.2k|        if ((a.position - b.position).SquareLength() > squareEpsilon) {
  ------------------
  |  Branch (108:13): [True: 0, False: 41.2k]
  ------------------
  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|  41.2k|        if ((a.normal - b.normal).SquareLength() > squareEpsilon) {
  ------------------
  |  Branch (116:13): [True: 1.60k, False: 39.6k]
  ------------------
  117|  1.60k|            return false;
  118|  1.60k|        }
  119|       |
  120|  39.6k|        if ((a.tangent - b.tangent).SquareLength() > squareEpsilon) {
  ------------------
  |  Branch (120:13): [True: 1.82k, False: 37.8k]
  ------------------
  121|  1.82k|            return false;
  122|  1.82k|        }
  123|       |
  124|  37.8k|        if ((a.bitangent - b.bitangent).SquareLength() > squareEpsilon) {
  ------------------
  |  Branch (124:13): [True: 306, False: 37.5k]
  ------------------
  125|    306|            return false;
  126|    306|        }
  127|       |
  128|   333k|        for (uint32_t i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; i ++) {
  ------------------
  |  Branch (128:30): [True: 296k, False: 37.0k]
  ------------------
  129|   296k|            if ((a.texcoords[i] - b.texcoords[i]).SquareLength() > squareEpsilon) {
  ------------------
  |  Branch (129:17): [True: 468, False: 296k]
  ------------------
  130|    468|                return false;
  131|    468|            }
  132|   296k|        }
  133|       |
  134|   332k|        for (uint32_t i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; i ++) {
  ------------------
  |  Branch (134:30): [True: 295k, False: 36.8k]
  ------------------
  135|   295k|            if (GetColorDifference(a.colors[i], b.colors[i]) > squareEpsilon) {
  ------------------
  |  Branch (135:17): [True: 156, False: 295k]
  ------------------
  136|    156|                return false;
  137|    156|            }
  138|   295k|        }
  139|       |
  140|       |        // If reached this point, they are ~equal
  141|  36.8k|        return true;
  142|  37.0k|    }
JoinVerticesProcess.cpp:_ZN12_GLOBAL__N_119updateXMeshVerticesI6aiMeshEEvPT_RNSt3__16vectorIiNS4_9allocatorIiEEEE:
  163|  1.89k|void updateXMeshVertices(XMesh *pMesh, std::vector<int> &uniqueVertices) {
  164|       |    // replace vertex data with the unique data sets
  165|  1.89k|    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|  1.89k|    if (pMesh->mVertices) {
  ------------------
  |  Branch (174:9): [True: 1.89k, False: 0]
  ------------------
  175|  1.89k|        std::unique_ptr<aiVector3D[]> oldVertices(pMesh->mVertices);
  176|  1.89k|        pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
  177|  20.8k|        for (unsigned int a = 0; a < pMesh->mNumVertices; a++)
  ------------------
  |  Branch (177:34): [True: 18.9k, False: 1.89k]
  ------------------
  178|  18.9k|            pMesh->mVertices[a] = oldVertices[uniqueVertices[a]];
  179|  1.89k|    }
  180|       |
  181|       |    // Normals, if present
  182|  1.89k|    if (pMesh->mNormals) {
  ------------------
  |  Branch (182:9): [True: 1.47k, False: 421]
  ------------------
  183|  1.47k|        std::unique_ptr<aiVector3D[]> oldNormals(pMesh->mNormals);
  184|  1.47k|        pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
  185|  17.5k|        for (unsigned int a = 0; a < pMesh->mNumVertices; a++)
  ------------------
  |  Branch (185:34): [True: 16.0k, False: 1.47k]
  ------------------
  186|  16.0k|            pMesh->mNormals[a] = oldNormals[uniqueVertices[a]];
  187|  1.47k|    }
  188|       |    // Tangents, if present
  189|  1.89k|    if (pMesh->mTangents) {
  ------------------
  |  Branch (189:9): [True: 264, False: 1.62k]
  ------------------
  190|    264|        std::unique_ptr<aiVector3D[]> oldTangents(pMesh->mTangents);
  191|    264|        pMesh->mTangents = new aiVector3D[pMesh->mNumVertices];
  192|  3.08k|        for (unsigned int a = 0; a < pMesh->mNumVertices; a++)
  ------------------
  |  Branch (192:34): [True: 2.81k, False: 264]
  ------------------
  193|  2.81k|            pMesh->mTangents[a] = oldTangents[uniqueVertices[a]];
  194|    264|    }
  195|       |    // Bitangents as well
  196|  1.89k|    if (pMesh->mBitangents) {
  ------------------
  |  Branch (196:9): [True: 264, False: 1.62k]
  ------------------
  197|    264|        std::unique_ptr<aiVector3D[]> oldBitangents(pMesh->mBitangents);
  198|    264|        pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices];
  199|  3.08k|        for (unsigned int a = 0; a < pMesh->mNumVertices; a++)
  ------------------
  |  Branch (199:34): [True: 2.81k, False: 264]
  ------------------
  200|  2.81k|            pMesh->mBitangents[a] = oldBitangents[uniqueVertices[a]];
  201|    264|    }
  202|       |    // Vertex colors
  203|  2.22k|    for (unsigned int a = 0; pMesh->HasVertexColors(a); a++) {
  ------------------
  |  Branch (203:30): [True: 332, False: 1.89k]
  ------------------
  204|    332|        std::unique_ptr<aiColor4D[]> oldColors(pMesh->mColors[a]);
  205|    332|        pMesh->mColors[a] = new aiColor4D[pMesh->mNumVertices];
  206|  1.63k|        for (unsigned int b = 0; b < pMesh->mNumVertices; b++)
  ------------------
  |  Branch (206:34): [True: 1.30k, False: 332]
  ------------------
  207|  1.30k|            pMesh->mColors[a][b] = oldColors[uniqueVertices[b]];
  208|    332|    }
  209|       |    // Texture coords
  210|  2.37k|    for (unsigned int a = 0; pMesh->HasTextureCoords(a); a++) {
  ------------------
  |  Branch (210:30): [True: 484, False: 1.89k]
  ------------------
  211|    484|        std::unique_ptr<aiVector3D[]> oldTextureCoords(pMesh->mTextureCoords[a]);
  212|    484|        pMesh->mTextureCoords[a] = new aiVector3D[pMesh->mNumVertices];
  213|  3.97k|        for (unsigned int b = 0; b < pMesh->mNumVertices; b++)
  ------------------
  |  Branch (213:34): [True: 3.48k, False: 484]
  ------------------
  214|  3.48k|            pMesh->mTextureCoords[a][b] = oldTextureCoords[uniqueVertices[b]];
  215|    484|    }
  216|  1.89k|}

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

_ZN6Assimp23LimitBoneWeightsProcessC2Ev:
   57|  3.24k|        mMaxWeights(AI_LMW_MAX_WEIGHTS), mRemoveEmptyBones(true) {
   58|       |    // empty
   59|  3.24k|}
_ZNK6Assimp23LimitBoneWeightsProcess8IsActiveEj:
   63|  1.27k|bool LimitBoneWeightsProcess::IsActive( unsigned int pFlags) const {
   64|  1.27k|    return (pFlags & aiProcess_LimitBoneWeights) != 0;
   65|  1.27k|}
_ZN6Assimp23LimitBoneWeightsProcess7ExecuteEP7aiScene:
   69|  1.27k|void LimitBoneWeightsProcess::Execute( aiScene* pScene) {
   70|  1.27k|    ai_assert(pScene != nullptr);
   71|       |
   72|  1.27k|    ASSIMP_LOG_DEBUG("LimitBoneWeightsProcess begin");
   73|       |
   74|  3.16k|    for (unsigned int m = 0; m < pScene->mNumMeshes; ++m) {
  ------------------
  |  Branch (74:30): [True: 1.89k, False: 1.27k]
  ------------------
   75|  1.89k|        ProcessMesh(pScene->mMeshes[m]);
   76|  1.89k|    }
   77|       |
   78|       |    ASSIMP_LOG_DEBUG("LimitBoneWeightsProcess end");
   79|  1.27k|}
_ZN6Assimp23LimitBoneWeightsProcess15SetupPropertiesEPKNS_8ImporterE:
   83|  1.27k|void LimitBoneWeightsProcess::SetupProperties(const Importer* pImp) {
   84|  1.27k|    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.27k|}
_ZN6Assimp23LimitBoneWeightsProcess11ProcessMeshEP6aiMesh:
  107|  1.89k|void LimitBoneWeightsProcess::ProcessMesh(aiMesh* pMesh) {
  108|  1.89k|    if (!pMesh->HasBones())
  ------------------
  |  Branch (108:9): [True: 1.61k, False: 275]
  ------------------
  109|  1.61k|        return;
  110|       |
  111|       |    // collect all bone weights per vertex
  112|    275|    typedef SmallVector<Weight,8> VertexWeightArray;
  113|    275|    typedef std::vector<VertexWeightArray> WeightsPerVertex;
  114|    275|    WeightsPerVertex vertexWeights(pMesh->mNumVertices);
  115|    275|    size_t maxVertexWeights = 0;
  116|       |
  117|  2.63k|    for (unsigned int b = 0; b < pMesh->mNumBones; ++b) {
  ------------------
  |  Branch (117:30): [True: 2.36k, False: 275]
  ------------------
  118|  2.36k|        const aiBone* bone = pMesh->mBones[b];
  119|  7.89k|        for (unsigned int w = 0; w < bone->mNumWeights; ++w) {
  ------------------
  |  Branch (119:34): [True: 5.52k, False: 2.36k]
  ------------------
  120|  5.52k|            const aiVertexWeight& vw = bone->mWeights[w];
  121|       |
  122|  5.52k|            if (vertexWeights.size() <= vw.mVertexId)
  ------------------
  |  Branch (122:17): [True: 31, False: 5.49k]
  ------------------
  123|     31|                continue;
  124|       |
  125|  5.49k|            vertexWeights[vw.mVertexId].push_back(Weight(b, vw.mWeight));
  126|  5.49k|            maxVertexWeights = std::max(maxVertexWeights, vertexWeights[vw.mVertexId].size());
  127|  5.49k|        }
  128|  2.36k|    }
  129|       |
  130|    275|    if (maxVertexWeights <= mMaxWeights)
  ------------------
  |  Branch (130:9): [True: 23, False: 252]
  ------------------
  131|     23|        return;
  132|       |
  133|    252|    unsigned int removed = 0, old_bones = pMesh->mNumBones;
  134|       |
  135|       |    // now cut the weight count if it exceeds the maximum
  136|  1.04k|    for (WeightsPerVertex::iterator vit = vertexWeights.begin(); vit != vertexWeights.end(); ++vit) {
  ------------------
  |  Branch (136:66): [True: 793, False: 252]
  ------------------
  137|    793|        if (vit->size() <= mMaxWeights)
  ------------------
  |  Branch (137:13): [True: 174, False: 619]
  ------------------
  138|    174|            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|    619|        std::sort(vit->begin(), vit->end());
  143|       |
  144|       |        // now kill everything beyond the maximum count
  145|    619|        unsigned int m = static_cast<unsigned int>(vit->size());
  146|    619|        vit->resize(mMaxWeights);
  147|    619|        removed += static_cast<unsigned int>(m - vit->size());
  148|       |
  149|       |        // and renormalize the weights
  150|    619|        float sum = 0.0f;
  151|  3.09k|        for(const Weight* it = vit->begin(); it != vit->end(); ++it) {
  ------------------
  |  Branch (151:46): [True: 2.47k, False: 619]
  ------------------
  152|  2.47k|            sum += it->mWeight;
  153|  2.47k|        }
  154|    619|        if (0.0f != sum) {
  ------------------
  |  Branch (154:13): [True: 587, False: 32]
  ------------------
  155|    587|            const float invSum = 1.0f / sum;
  156|  2.93k|            for(Weight* it = vit->begin(); it != vit->end(); ++it) {
  ------------------
  |  Branch (156:44): [True: 2.34k, False: 587]
  ------------------
  157|  2.34k|                it->mWeight *= invSum;
  158|  2.34k|            }
  159|    587|        }
  160|    619|    }
  161|       |
  162|       |    // clear weight count for all bone
  163|  2.55k|    for (unsigned int a = 0; a < pMesh->mNumBones; ++a) {
  ------------------
  |  Branch (163:30): [True: 2.30k, False: 252]
  ------------------
  164|  2.30k|        pMesh->mBones[a]->mNumWeights = 0;
  165|  2.30k|    }
  166|       |
  167|       |    // rebuild the vertex weight array for all bones
  168|  1.04k|    for (unsigned int a = 0; a < vertexWeights.size(); ++a) {
  ------------------
  |  Branch (168:30): [True: 793, False: 252]
  ------------------
  169|    793|        const VertexWeightArray& vw = vertexWeights[a];
  170|  3.68k|        for (const Weight* it = vw.begin(); it != vw.end(); ++it) {
  ------------------
  |  Branch (170:45): [True: 2.89k, False: 793]
  ------------------
  171|  2.89k|            aiBone* bone = pMesh->mBones[it->mBone];
  172|  2.89k|            bone->mWeights[bone->mNumWeights++] = aiVertexWeight(a, it->mWeight);
  173|  2.89k|        }
  174|    793|    }
  175|       |
  176|       |    // remove empty bones
  177|    252|    if (mRemoveEmptyBones) {
  ------------------
  |  Branch (177:9): [True: 252, False: 0]
  ------------------
  178|    252|        pMesh->mNumBones = removeEmptyBones(pMesh);
  179|    252|    }
  180|       |
  181|    252|    if (!DefaultLogger::isNullLogger()) {
  ------------------
  |  Branch (181:9): [True: 0, False: 252]
  ------------------
  182|       |        ASSIMP_LOG_INFO("Removed ", removed, " weights. Input bones: ", old_bones, ". Output bones: ", pMesh->mNumBones);
  183|      0|    }
  184|    252|}
LimitBoneWeightsProcess.cpp:_ZN6AssimpL16removeEmptyBonesEP6aiMesh:
   89|    252|static unsigned int removeEmptyBones(aiMesh *pMesh) {
   90|    252|    ai_assert(pMesh != nullptr);
   91|       |
   92|    252|    unsigned int writeBone = 0;
   93|  2.55k|    for (unsigned int readBone = 0; readBone< pMesh->mNumBones; ++readBone) {
  ------------------
  |  Branch (93:37): [True: 2.30k, False: 252]
  ------------------
   94|  2.30k|        aiBone* bone = pMesh->mBones[readBone];
   95|  2.30k|        if (bone->mNumWeights > 0) {
  ------------------
  |  Branch (95:13): [True: 1.09k, False: 1.21k]
  ------------------
   96|  1.09k|            pMesh->mBones[writeBone++] = bone;
   97|  1.21k|        } else {
   98|  1.21k|            delete bone;
   99|  1.21k|        }
  100|  2.30k|    }
  101|       |
  102|    252|    return writeBone;
  103|    252|}

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

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

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

_ZN6Assimp21OptimizeMeshesProcessC2Ev:
   66|  3.24k|    , pts(false)
   67|  3.24k|    , max_verts( NotSet )
   68|  3.24k|    , max_faces( NotSet ) {
   69|       |    // empty
   70|  3.24k|}
_ZNK6Assimp21OptimizeMeshesProcess8IsActiveEj:
   75|  1.27k|{
   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.27k|    if( 0 != (pFlags & aiProcess_OptimizeMeshes) ) {
  ------------------
  |  Branch (80:9): [True: 0, False: 1.27k]
  ------------------
   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.27k|    return false;
   86|  1.27k|}

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

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

_ZN6Assimp22ComputePositionEpsilonEPK6aiMesh:
  136|  1.89k|ai_real ComputePositionEpsilon(const aiMesh *pMesh) {
  137|  1.89k|    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|  1.89k|    aiVector3D minVec, maxVec;
  141|  1.89k|    ArrayBounds(pMesh->mVertices, pMesh->mNumVertices, minVec, maxVec);
  142|  1.89k|    return (maxVec - minVec).Length() * epsilon;
  143|  1.89k|}
_ZN6Assimp28ComputeVertexBoneWeightTableEPK6aiMesh:
  199|    809|VertexWeightTable *ComputeVertexBoneWeightTable(const aiMesh *pMesh) {
  200|    809|    if (!pMesh || !pMesh->mNumVertices || !pMesh->mNumBones) {
  ------------------
  |  Branch (200:9): [True: 0, False: 809]
  |  Branch (200:19): [True: 0, False: 809]
  |  Branch (200:43): [True: 675, False: 134]
  ------------------
  201|    675|        return nullptr;
  202|    675|    }
  203|       |
  204|    134|    VertexWeightTable *avPerVertexWeights = new VertexWeightTable[pMesh->mNumVertices];
  205|  1.45k|    for (unsigned int i = 0; i < pMesh->mNumBones; ++i) {
  ------------------
  |  Branch (205:30): [True: 1.32k, False: 134]
  ------------------
  206|       |
  207|  1.32k|        aiBone *bone = pMesh->mBones[i];
  208|  3.92k|        for (unsigned int a = 0; a < bone->mNumWeights; ++a) {
  ------------------
  |  Branch (208:34): [True: 2.59k, False: 1.32k]
  ------------------
  209|  2.59k|            const aiVertexWeight &weight = bone->mWeights[a];
  210|  2.59k|            avPerVertexWeights[weight.mVertexId].emplace_back(i, weight.mWeight);
  211|  2.59k|        }
  212|  1.32k|    }
  213|    134|    return avPerVertexWeights;
  214|    809|}

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

_ZN6Assimp26RemoveRedundantMatsProcessC2Ev:
   57|  3.24k|RemoveRedundantMatsProcess::RemoveRedundantMatsProcess() : mConfigFixedMaterials() {}
_ZNK6Assimp26RemoveRedundantMatsProcess8IsActiveEj:
   61|  1.32k|bool RemoveRedundantMatsProcess::IsActive( unsigned int pFlags) const {
   62|  1.32k|    return (pFlags & aiProcess_RemoveRedundantMaterials) != 0;
   63|  1.32k|}
_ZN6Assimp26RemoveRedundantMatsProcess15SetupPropertiesEPKNS_8ImporterE:
   67|  1.32k|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.32k|}
_ZN6Assimp26RemoveRedundantMatsProcess7ExecuteEP7aiScene:
   74|  1.32k|void RemoveRedundantMatsProcess::Execute( aiScene* pScene) {
   75|  1.32k|    ASSIMP_LOG_DEBUG("RemoveRedundantMatsProcess begin");
   76|       |
   77|  1.32k|    unsigned int redundantRemoved = 0, unreferencedRemoved = 0;
   78|  1.32k|    if (pScene->mNumMaterials == 0) {
  ------------------
  |  Branch (78:9): [True: 0, False: 1.32k]
  ------------------
   79|      0|        return;
   80|      0|    }
   81|       |
   82|       |    // Find out which materials are referenced by meshes
   83|  1.32k|    std::vector<bool> abReferenced(pScene->mNumMaterials,false);
   84|  2.50k|    for (unsigned int i = 0;i < pScene->mNumMeshes;++i) {
  ------------------
  |  Branch (84:29): [True: 1.17k, False: 1.32k]
  ------------------
   85|  1.17k|        abReferenced[pScene->mMeshes[i]->mMaterialIndex] = true;
   86|  1.17k|    }
   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.32k|    if (mConfigFixedMaterials.length()) {
  ------------------
  |  Branch (91:9): [True: 0, False: 1.32k]
  ------------------
   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.32k|    unsigned int *aiMappingTable = new unsigned int[pScene->mNumMaterials];
  119|  3.61k|    for ( unsigned int i=0; i<pScene->mNumMaterials; i++ ) {
  ------------------
  |  Branch (119:29): [True: 2.28k, False: 1.32k]
  ------------------
  120|  2.28k|        aiMappingTable[ i ] = 0;
  121|  2.28k|    }
  122|  1.32k|    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.32k|    uint32_t *aiHashes = new uint32_t[ pScene->mNumMaterials ];
  129|  3.61k|    for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
  ------------------
  |  Branch (129:30): [True: 2.28k, False: 1.32k]
  ------------------
  130|       |        // No mesh is referencing this material, remove it.
  131|  2.28k|        if (!abReferenced[i]) {
  ------------------
  |  Branch (131:13): [True: 1.10k, False: 1.17k]
  ------------------
  132|  1.10k|            ++unreferencedRemoved;
  133|  1.10k|            delete pScene->mMaterials[i];
  134|  1.10k|            pScene->mMaterials[i] = nullptr;
  135|  1.10k|            continue;
  136|  1.10k|        }
  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.17k|        uint32_t me = aiHashes[i] = ComputeMaterialHash(pScene->mMaterials[i]);
  141|  1.17k|        for (unsigned int a = 0; a < i;++a) {
  ------------------
  |  Branch (141:34): [True: 0, False: 1.17k]
  ------------------
  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.17k|        if (me) {
  ------------------
  |  Branch (152:13): [True: 1.17k, False: 0]
  ------------------
  153|  1.17k|            aiMappingTable[i] = iNewNum++;
  154|  1.17k|        }
  155|  1.17k|    }
  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.32k|    if (iNewNum < 1) {
  ------------------
  |  Branch (158:9): [True: 145, False: 1.17k]
  ------------------
  159|    145|        delete [] aiMappingTable;
  160|    145|        delete [] aiHashes;
  161|    145|        pScene->mNumMaterials = 0;
  162|    145|        return;
  163|    145|    }
  164|  1.17k|    if (iNewNum != pScene->mNumMaterials) {
  ------------------
  |  Branch (164:9): [True: 964, False: 215]
  ------------------
  165|    964|        ai_assert(iNewNum > 0);
  166|    964|        aiMaterial** ppcMaterials = new aiMaterial*[iNewNum];
  167|    964|        ::memset(ppcMaterials,0,sizeof(void*)*iNewNum);
  168|  2.89k|        for (unsigned int p = 0; p < pScene->mNumMaterials;++p) {
  ------------------
  |  Branch (168:34): [True: 1.92k, False: 964]
  ------------------
  169|       |            // if the material is not referenced ... remove it
  170|  1.92k|            if (!abReferenced[p]) {
  ------------------
  |  Branch (170:17): [True: 964, False: 964]
  ------------------
  171|    964|                continue;
  172|    964|            }
  173|       |
  174|       |            // generate new names for modified materials that had no names
  175|    964|            const unsigned int idx = aiMappingTable[p];
  176|    964|            if (ppcMaterials[idx]) {
  ------------------
  |  Branch (176:17): [True: 0, False: 964]
  ------------------
  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|    964|            } else {
  183|    964|                ppcMaterials[idx] = pScene->mMaterials[p];
  184|    964|            }
  185|    964|        }
  186|       |        // update all material indices
  187|  1.92k|        for (unsigned int p = 0; p < pScene->mNumMeshes;++p) {
  ------------------
  |  Branch (187:34): [True: 964, False: 964]
  ------------------
  188|    964|            aiMesh* mesh = pScene->mMeshes[p];
  189|    964|            ai_assert(nullptr != mesh);
  190|    964|            mesh->mMaterialIndex = aiMappingTable[mesh->mMaterialIndex];
  191|    964|        }
  192|       |        // delete the old material list
  193|    964|        delete[] pScene->mMaterials;
  194|    964|        pScene->mMaterials = ppcMaterials;
  195|    964|        pScene->mNumMaterials = iNewNum;
  196|    964|    }
  197|       |    // delete temporary storage
  198|  1.17k|    delete[] aiHashes;
  199|  1.17k|    delete[] aiMappingTable;
  200|       |
  201|  1.17k|    if (redundantRemoved == 0 && unreferencedRemoved == 0) {
  ------------------
  |  Branch (201:9): [True: 1.17k, False: 0]
  |  Branch (201:34): [True: 215, False: 964]
  ------------------
  202|    215|        ASSIMP_LOG_DEBUG("RemoveRedundantMatsProcess finished ");
  203|    964|    } else {
  204|       |        ASSIMP_LOG_INFO("RemoveRedundantMatsProcess finished. Removed ", redundantRemoved, " redundant and ",
  205|    964|            unreferencedRemoved, " unused materials.");
  206|    964|    }
  207|  1.17k|}

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

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

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

_ZN6Assimp18SortByPTypeProcessC2Ev:
   55|  3.24k|SortByPTypeProcess::SortByPTypeProcess() : mConfigRemoveMeshes(0) {}
_ZNK6Assimp18SortByPTypeProcess8IsActiveEj:
   59|  1.32k|bool SortByPTypeProcess::IsActive(unsigned int pFlags) const {
   60|  1.32k|    return (pFlags & aiProcess_SortByPType) != 0;
   61|  1.32k|}
_ZN6Assimp18SortByPTypeProcess15SetupPropertiesEPKNS_8ImporterE:
   64|  1.32k|void SortByPTypeProcess::SetupProperties(const Importer *pImp) {
   65|       |    mConfigRemoveMeshes = pImp->GetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, 0);
   66|  1.32k|}
_Z11UpdateNodesRKNSt3__16vectorIjNS_9allocatorIjEEEEP6aiNode:
   77|  4.37k|void UpdateNodes(const std::vector<unsigned int> &replaceMeshIndex, aiNode *node) {
   78|  4.37k|    ai_assert(node != nullptr);
   79|       |
   80|  4.37k|    if (node->mNumMeshes) {
  ------------------
  |  Branch (80:9): [True: 862, False: 3.51k]
  ------------------
   81|    862|        unsigned int newSize = 0;
   82|  1.72k|        for (unsigned int m = 0; m < node->mNumMeshes; ++m) {
  ------------------
  |  Branch (82:34): [True: 862, False: 862]
  ------------------
   83|    862|            unsigned int add = node->mMeshes[m] << 2;
   84|  4.31k|            for (unsigned int i = 0; i < 4; ++i) {
  ------------------
  |  Branch (84:38): [True: 3.44k, False: 862]
  ------------------
   85|  3.44k|                if (UINT_MAX != replaceMeshIndex[add + i]) {
  ------------------
  |  Branch (85:21): [True: 1.97k, False: 1.47k]
  ------------------
   86|  1.97k|                    ++newSize;
   87|  1.97k|                }
   88|  3.44k|            }
   89|    862|        }
   90|    862|        if (newSize == 0) {
  ------------------
  |  Branch (90:13): [True: 0, False: 862]
  ------------------
   91|      0|            clearMeshesInNode(node);
   92|      0|            return;
   93|      0|        }
   94|       |
   95|       |        // Try to reuse the old array if possible
   96|    862|        unsigned int *newMeshes = (newSize > node->mNumMeshes ? new unsigned int[newSize] : node->mMeshes);
  ------------------
  |  Branch (96:36): [True: 862, False: 0]
  ------------------
   97|  1.72k|        for (unsigned int m = 0; m < node->mNumMeshes; ++m) {
  ------------------
  |  Branch (97:34): [True: 862, False: 862]
  ------------------
   98|    862|            unsigned int add = node->mMeshes[m] << 2;
   99|  4.31k|            for (unsigned int i = 0; i < 4; ++i) {
  ------------------
  |  Branch (99:38): [True: 3.44k, False: 862]
  ------------------
  100|  3.44k|                if (UINT_MAX != replaceMeshIndex[add + i]) {
  ------------------
  |  Branch (100:21): [True: 1.97k, False: 1.47k]
  ------------------
  101|  1.97k|                    *newMeshes++ = replaceMeshIndex[add + i];
  102|  1.97k|                }
  103|  3.44k|            }
  104|    862|        }
  105|    862|        if (newSize > node->mNumMeshes) {
  ------------------
  |  Branch (105:13): [True: 862, False: 0]
  ------------------
  106|    862|            clearMeshesInNode(node);
  107|    862|        }
  108|    862|        node->mMeshes = newMeshes - (node->mNumMeshes = newSize);
  109|    862|    }
  110|       |
  111|       |    // call all subnodes recursively
  112|  7.94k|    for (unsigned int m = 0; m < node->mNumChildren; ++m) {
  ------------------
  |  Branch (112:30): [True: 3.56k, False: 4.37k]
  ------------------
  113|  3.56k|        UpdateNodes(replaceMeshIndex, node->mChildren[m]);
  114|  3.56k|    }
  115|  4.37k|}
_ZN6Assimp18SortByPTypeProcess7ExecuteEP7aiScene:
  119|  1.32k|void SortByPTypeProcess::Execute(aiScene *pScene) {
  120|  1.32k|    if (0 == pScene->mNumMeshes) {
  ------------------
  |  Branch (120:9): [True: 145, False: 1.17k]
  ------------------
  121|    145|        ASSIMP_LOG_DEBUG("SortByPTypeProcess skipped, there are no meshes");
  122|    145|        return;
  123|    145|    }
  124|       |
  125|  1.32k|    ASSIMP_LOG_DEBUG("SortByPTypeProcess begin");
  126|       |
  127|  1.17k|    unsigned int aiNumMeshesPerPType[4] = { 0, 0, 0, 0 };
  128|       |
  129|  1.17k|    std::vector<aiMesh *> outMeshes;
  130|  1.17k|    outMeshes.reserve(static_cast<size_t>(pScene->mNumMeshes) << 1u);
  131|       |
  132|  1.17k|    bool bAnyChanges = false;
  133|       |
  134|  1.17k|    std::vector<unsigned int> replaceMeshIndex(pScene->mNumMeshes * 4, UINT_MAX);
  135|  1.17k|    std::vector<unsigned int>::iterator meshIdx = replaceMeshIndex.begin();
  136|  2.35k|    for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
  ------------------
  |  Branch (136:30): [True: 1.17k, False: 1.17k]
  ------------------
  137|  1.17k|        aiMesh *const mesh = pScene->mMeshes[i];
  138|  1.17k|        if (mesh->mPrimitiveTypes == 0) {
  ------------------
  |  Branch (138:13): [True: 0, False: 1.17k]
  ------------------
  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.17k|        unsigned int num = 0;
  147|  1.17k|        if (mesh->mPrimitiveTypes & aiPrimitiveType_POINT) {
  ------------------
  |  Branch (147:13): [True: 611, False: 568]
  ------------------
  148|    611|            ++aiNumMeshesPerPType[0];
  149|    611|            ++num;
  150|    611|        }
  151|  1.17k|        if (mesh->mPrimitiveTypes & aiPrimitiveType_LINE) {
  ------------------
  |  Branch (151:13): [True: 839, False: 340]
  ------------------
  152|    839|            ++aiNumMeshesPerPType[1];
  153|    839|            ++num;
  154|    839|        }
  155|  1.17k|        if (mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE) {
  ------------------
  |  Branch (155:13): [True: 758, False: 421]
  ------------------
  156|    758|            ++aiNumMeshesPerPType[2];
  157|    758|            ++num;
  158|    758|        }
  159|  1.17k|        if (mesh->mPrimitiveTypes & aiPrimitiveType_POLYGON) {
  ------------------
  |  Branch (159:13): [True: 0, False: 1.17k]
  ------------------
  160|      0|            ++aiNumMeshesPerPType[3];
  161|      0|            ++num;
  162|      0|        }
  163|       |
  164|  1.17k|        if (1 == num) {
  ------------------
  |  Branch (164:13): [True: 370, False: 809]
  ------------------
  165|    370|            if (!(mConfigRemoveMeshes & mesh->mPrimitiveTypes)) {
  ------------------
  |  Branch (165:17): [True: 370, False: 0]
  ------------------
  166|    370|                *meshIdx = static_cast<unsigned int>(outMeshes.size());
  167|    370|                outMeshes.emplace_back(mesh);
  168|    370|                pScene->mMeshes[i] = nullptr; // Indicate ownership transfer
  169|    370|            } else {
  170|      0|                delete mesh;
  171|      0|                pScene->mMeshes[i] = nullptr;
  172|      0|                bAnyChanges = true;
  173|      0|            }
  174|       |
  175|    370|            meshIdx += 4;
  176|    370|            continue;
  177|    370|        }
  178|    809|        bAnyChanges = true;
  179|       |
  180|       |        // reuse our current mesh arrays for the submesh
  181|       |        // with the largest number of primitives
  182|    809|        unsigned int aiNumPerPType[4] = { 0, 0, 0, 0 };
  183|    809|        aiFace *pFirstFace = mesh->mFaces;
  184|    809|        if (pFirstFace == nullptr) {
  ------------------
  |  Branch (184:13): [True: 0, False: 809]
  ------------------
  185|      0|            continue;
  186|      0|        }
  187|       |
  188|    809|        aiFace *const pLastFace = pFirstFace + mesh->mNumFaces;
  189|       |
  190|    809|        unsigned int numPolyVerts = 0;
  191|  22.6k|        for (; pFirstFace != pLastFace; ++pFirstFace) {
  ------------------
  |  Branch (191:16): [True: 21.8k, False: 809]
  ------------------
  192|  21.8k|            if (pFirstFace->mNumIndices >= 1 && pFirstFace->mNumIndices <= 3)
  ------------------
  |  Branch (192:17): [True: 21.8k, False: 0]
  |  Branch (192:49): [True: 21.8k, False: 0]
  ------------------
  193|  21.8k|                ++aiNumPerPType[pFirstFace->mNumIndices - 1];
  194|      0|            else {
  195|      0|                ++aiNumPerPType[3];
  196|      0|                numPolyVerts += pFirstFace->mNumIndices;
  197|      0|            }
  198|  21.8k|            if (pFirstFace->mNumIndices == 0) {
  ------------------
  |  Branch (198:17): [True: 0, False: 21.8k]
  ------------------
  199|      0|                ASSIMP_LOG_WARN("Face with 0 indices treated as polygon");
  200|      0|            }
  201|  21.8k|        }
  202|       |
  203|    809|        VertexWeightTable *avw = ComputeVertexBoneWeightTable(mesh);
  204|  4.04k|        for (unsigned int real = 0; real < 4; ++real, ++meshIdx) {
  ------------------
  |  Branch (204:37): [True: 3.23k, False: 809]
  ------------------
  205|  3.23k|            if (!aiNumPerPType[real] || mConfigRemoveMeshes & (1u << real)) {
  ------------------
  |  Branch (205:17): [True: 1.39k, False: 1.83k]
  |  Branch (205:41): [True: 0, False: 1.83k]
  ------------------
  206|  1.39k|                continue;
  207|  1.39k|            }
  208|       |
  209|  1.83k|            *meshIdx = (unsigned int)outMeshes.size();
  210|  1.83k|            outMeshes.push_back(new aiMesh());
  211|  1.83k|            aiMesh *out = outMeshes.back();
  212|       |
  213|       |            // the name carries the adjacency information between the meshes
  214|  1.83k|            out->mName = mesh->mName;
  215|       |
  216|       |            // copy data members
  217|  1.83k|            out->mPrimitiveTypes = 1u << real;
  218|  1.83k|            out->mMaterialIndex = mesh->mMaterialIndex;
  219|       |
  220|       |            // allocate output storage
  221|  1.83k|            out->mNumFaces = aiNumPerPType[real];
  222|  1.83k|            aiFace *outFaces = out->mFaces = new aiFace[out->mNumFaces];
  223|       |
  224|  1.83k|            out->mNumVertices = (3 == real ? numPolyVerts : out->mNumFaces * (real + 1));
  ------------------
  |  Branch (224:34): [True: 0, False: 1.83k]
  ------------------
  225|       |
  226|  1.83k|            aiVector3D *vert(nullptr), *nor(nullptr), *tan(nullptr), *bit(nullptr);
  227|  1.83k|            aiVector3D *uv[AI_MAX_NUMBER_OF_TEXTURECOORDS];
  228|  1.83k|            aiColor4D *cols[AI_MAX_NUMBER_OF_COLOR_SETS];
  229|       |
  230|  1.83k|            if (mesh->mVertices) {
  ------------------
  |  Branch (230:17): [True: 1.83k, False: 0]
  ------------------
  231|  1.83k|                vert = out->mVertices = new aiVector3D[out->mNumVertices];
  232|  1.83k|            }
  233|       |
  234|  1.83k|            if (mesh->mNormals) {
  ------------------
  |  Branch (234:17): [True: 1.11k, False: 724]
  ------------------
  235|  1.11k|                nor = out->mNormals = new aiVector3D[out->mNumVertices];
  236|  1.11k|            }
  237|       |
  238|  1.83k|            if (mesh->mTangents) {
  ------------------
  |  Branch (238:17): [True: 48, False: 1.79k]
  ------------------
  239|     48|                tan = out->mTangents = new aiVector3D[out->mNumVertices];
  240|     48|                bit = out->mBitangents = new aiVector3D[out->mNumVertices];
  241|     48|            }
  242|       |
  243|  16.5k|            for (unsigned int j = 0; j < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++j) {
  ------------------
  |  Branch (243:38): [True: 14.7k, False: 1.83k]
  ------------------
  244|  14.7k|                uv[j] = nullptr;
  245|  14.7k|                if (mesh->mTextureCoords[j]) {
  ------------------
  |  Branch (245:21): [True: 560, False: 14.1k]
  ------------------
  246|    560|                    uv[j] = out->mTextureCoords[j] = new aiVector3D[out->mNumVertices];
  247|    560|                }
  248|       |
  249|  14.7k|                out->mNumUVComponents[j] = mesh->mNumUVComponents[j];
  250|  14.7k|            }
  251|       |
  252|  16.5k|            for (unsigned int j = 0; j < AI_MAX_NUMBER_OF_COLOR_SETS; ++j) {
  ------------------
  |  Branch (252:38): [True: 14.7k, False: 1.83k]
  ------------------
  253|  14.7k|                cols[j] = nullptr;
  254|  14.7k|                if (mesh->mColors[j]) {
  ------------------
  |  Branch (254:21): [True: 321, False: 14.3k]
  ------------------
  255|    321|                    cols[j] = out->mColors[j] = new aiColor4D[out->mNumVertices];
  256|    321|                }
  257|  14.7k|            }
  258|       |
  259|  1.83k|            if (mesh->mNumAnimMeshes > 0 && mesh->mAnimMeshes) {
  ------------------
  |  Branch (259:17): [True: 0, False: 1.83k]
  |  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|  1.83k|            for (unsigned int j = 0; j < mesh->mNumAnimMeshes; ++j) {
  ------------------
  |  Branch (264:38): [True: 0, False: 1.83k]
  ------------------
  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|  1.83k|            typedef std::vector<aiVertexWeight> TempBoneInfo;
  299|  1.83k|            std::vector<TempBoneInfo> tempBones(mesh->mNumBones);
  300|       |
  301|       |            // try to guess how much storage we'll need
  302|  4.51k|            for (unsigned int q = 0; q < mesh->mNumBones; ++q) {
  ------------------
  |  Branch (302:38): [True: 2.67k, False: 1.83k]
  ------------------
  303|  2.67k|                tempBones[q].reserve(mesh->mBones[q]->mNumWeights / (num - 1));
  304|  2.67k|            }
  305|       |
  306|  1.83k|            unsigned int outIdx = 0;
  307|  1.83k|            unsigned int amIdx = 0; // AnimMesh index
  308|  50.7k|            for (unsigned int m = 0; m < mesh->mNumFaces; ++m) {
  ------------------
  |  Branch (308:38): [True: 48.9k, False: 1.83k]
  ------------------
  309|  48.9k|                aiFace &in = mesh->mFaces[m];
  310|  48.9k|                if ((real == 3 && in.mNumIndices <= 3) || (real != 3 && in.mNumIndices != real + 1)) {
  ------------------
  |  Branch (310:22): [True: 0, False: 48.9k]
  |  Branch (310:35): [True: 0, False: 0]
  |  Branch (310:60): [True: 48.9k, False: 0]
  |  Branch (310:73): [True: 27.0k, False: 21.8k]
  ------------------
  311|  27.0k|                    continue;
  312|  27.0k|                }
  313|       |
  314|  21.8k|                outFaces->mNumIndices = in.mNumIndices;
  315|  21.8k|                outFaces->mIndices = in.mIndices;
  316|       |
  317|  76.9k|                for (unsigned int q = 0; q < in.mNumIndices; ++q) {
  ------------------
  |  Branch (317:42): [True: 55.0k, False: 21.8k]
  ------------------
  318|  55.0k|                    unsigned int idx = in.mIndices[q];
  319|       |
  320|       |                    // process all bones of this index
  321|  55.0k|                    if (avw) {
  ------------------
  |  Branch (321:25): [True: 947, False: 54.1k]
  ------------------
  322|    947|                        VertexWeightTable &tbl = avw[idx];
  323|    947|                        for (VertexWeightTable::const_iterator it = tbl.begin(), end = tbl.end();
  324|  7.35k|                                it != end; ++it) {
  ------------------
  |  Branch (324:33): [True: 6.41k, False: 947]
  ------------------
  325|  6.41k|                            tempBones[(*it).first].emplace_back(outIdx, (*it).second);
  326|  6.41k|                        }
  327|    947|                    }
  328|       |
  329|  55.0k|                    if (vert) {
  ------------------
  |  Branch (329:25): [True: 55.0k, False: 0]
  ------------------
  330|  55.0k|                        *vert++ = mesh->mVertices[idx];
  331|  55.0k|                    }
  332|  55.0k|                    if (nor)
  ------------------
  |  Branch (332:25): [True: 13.1k, False: 41.9k]
  ------------------
  333|  13.1k|                        *nor++ = mesh->mNormals[idx];
  334|  55.0k|                    if (tan) {
  ------------------
  |  Branch (334:25): [True: 327, False: 54.7k]
  ------------------
  335|    327|                        *tan++ = mesh->mTangents[idx];
  336|    327|                        *bit++ = mesh->mBitangents[idx];
  337|    327|                    }
  338|       |
  339|  60.0k|                    for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++pp) {
  ------------------
  |  Branch (339:47): [True: 60.0k, False: 0]
  ------------------
  340|  60.0k|                        if (!uv[pp])
  ------------------
  |  Branch (340:29): [True: 55.0k, False: 4.98k]
  ------------------
  341|  55.0k|                            break;
  342|  4.98k|                        *uv[pp]++ = mesh->mTextureCoords[pp][idx];
  343|  4.98k|                    }
  344|       |
  345|  56.5k|                    for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_COLOR_SETS; ++pp) {
  ------------------
  |  Branch (345:47): [True: 56.5k, False: 0]
  ------------------
  346|  56.5k|                        if (!cols[pp])
  ------------------
  |  Branch (346:29): [True: 55.0k, False: 1.46k]
  ------------------
  347|  55.0k|                            break;
  348|  1.46k|                        *cols[pp]++ = mesh->mColors[pp][idx];
  349|  1.46k|                    }
  350|       |
  351|  55.0k|                    unsigned int pp = 0;
  352|  55.0k|                    for (; pp < mesh->mNumAnimMeshes; ++pp) {
  ------------------
  |  Branch (352:28): [True: 0, False: 55.0k]
  ------------------
  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|  55.0k|                    if (pp == mesh->mNumAnimMeshes)
  ------------------
  |  Branch (372:25): [True: 55.0k, False: 0]
  ------------------
  373|  55.0k|                        ++amIdx;
  374|       |
  375|  55.0k|                    in.mIndices[q] = outIdx++;
  376|  55.0k|                }
  377|       |
  378|  21.8k|                in.mIndices = nullptr;
  379|  21.8k|                ++outFaces;
  380|  21.8k|            }
  381|  1.83k|            ai_assert(outFaces == out->mFaces + out->mNumFaces);
  382|       |
  383|       |            // now generate output bones
  384|  4.51k|            for (unsigned int q = 0; q < mesh->mNumBones; ++q) {
  ------------------
  |  Branch (384:38): [True: 2.67k, False: 1.83k]
  ------------------
  385|  2.67k|                if (!tempBones[q].empty()) {
  ------------------
  |  Branch (385:21): [True: 2.24k, False: 432]
  ------------------
  386|  2.24k|                    ++out->mNumBones;
  387|  2.24k|                }
  388|  2.67k|            }
  389|       |
  390|  1.83k|            if (out->mNumBones) {
  ------------------
  |  Branch (390:17): [True: 267, False: 1.57k]
  ------------------
  391|    267|                out->mBones = new aiBone *[out->mNumBones];
  392|  2.90k|                for (unsigned int q = 0, boneIdx = 0; q < mesh->mNumBones; ++q) {
  ------------------
  |  Branch (392:55): [True: 2.63k, False: 267]
  ------------------
  393|  2.63k|                    TempBoneInfo &in = tempBones[q];
  394|  2.63k|                    if (in.empty()) {
  ------------------
  |  Branch (394:25): [True: 392, False: 2.24k]
  ------------------
  395|    392|                        continue;
  396|    392|                    }
  397|       |
  398|  2.24k|                    aiBone *srcBone = mesh->mBones[q];
  399|  2.24k|                    aiBone *bone = out->mBones[boneIdx] = new aiBone();
  400|       |
  401|  2.24k|                    bone->mName = srcBone->mName;
  402|  2.24k|                    bone->mOffsetMatrix = srcBone->mOffsetMatrix;
  403|       |
  404|  2.24k|                    bone->mNumWeights = (unsigned int)in.size();
  405|  2.24k|                    bone->mWeights = new aiVertexWeight[bone->mNumWeights];
  406|       |
  407|  2.24k|                    ::memcpy(bone->mWeights, &in[0], bone->mNumWeights * sizeof(aiVertexWeight));
  408|       |
  409|  2.24k|                    ++boneIdx;
  410|  2.24k|                }
  411|    267|            }
  412|  1.83k|        }
  413|       |
  414|       |        // delete the per-vertex bone weights table
  415|    809|        delete[] avw;
  416|       |
  417|       |        // delete the input mesh
  418|    809|        delete mesh;
  419|       |
  420|       |        // avoid invalid pointer
  421|    809|        pScene->mMeshes[i] = nullptr;
  422|    809|    }
  423|       |
  424|  1.17k|    if (outMeshes.empty()) {
  ------------------
  |  Branch (424:9): [True: 0, False: 1.17k]
  ------------------
  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.17k|    if (bAnyChanges) {
  ------------------
  |  Branch (431:9): [True: 809, False: 370]
  ------------------
  432|    809|        UpdateNodes(replaceMeshIndex, pScene->mRootNode);
  433|    809|    }
  434|       |
  435|  1.17k|    if (outMeshes.size() != pScene->mNumMeshes) {
  ------------------
  |  Branch (435:9): [True: 809, False: 370]
  ------------------
  436|    809|        delete[] pScene->mMeshes;
  437|    809|        pScene->mNumMeshes = (unsigned int)outMeshes.size();
  438|    809|        pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
  439|    809|    }
  440|  1.17k|    ::memcpy(pScene->mMeshes, &outMeshes[0], pScene->mNumMeshes * sizeof(void *));
  441|       |
  442|  1.17k|    if (!DefaultLogger::isNullLogger()) {
  ------------------
  |  Branch (442:9): [True: 0, False: 1.17k]
  ------------------
  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.17k|}
SortByPTypeProcess.cpp:_ZL17clearMeshesInNodeP6aiNode:
   69|    862|static void clearMeshesInNode(aiNode *node) {
   70|    862|    delete[] node->mMeshes;
   71|    862|    node->mNumMeshes = 0;
   72|    862|    node->mMeshes = nullptr;
   73|    862|}

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

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

_ZN6Assimp32SplitLargeMeshesProcess_TriangleC2Ev:
   51|  3.24k|SplitLargeMeshesProcess_Triangle::SplitLargeMeshesProcess_Triangle() {
   52|       |    LIMIT = AI_SLM_DEFAULT_MAX_TRIANGLES;
   53|  3.24k|}
_ZNK6Assimp32SplitLargeMeshesProcess_Triangle8IsActiveEj:
   57|  1.27k|bool SplitLargeMeshesProcess_Triangle::IsActive( unsigned int pFlags) const {
   58|  1.27k|    return (pFlags & aiProcess_SplitLargeMeshes) != 0;
   59|  1.27k|}
_ZN6Assimp32SplitLargeMeshesProcess_Triangle7ExecuteEP7aiScene:
   63|  1.27k|void SplitLargeMeshesProcess_Triangle::Execute( aiScene* pScene) {
   64|  1.27k|    if (0xffffffff == this->LIMIT || nullptr == pScene ) {
  ------------------
  |  Branch (64:9): [True: 0, False: 1.27k]
  |  Branch (64:38): [True: 0, False: 1.27k]
  ------------------
   65|      0|        return;
   66|      0|    }
   67|       |
   68|  1.27k|    ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Triangle begin");
   69|  1.27k|    std::vector<std::pair<aiMesh*, unsigned int> > avList;
   70|       |
   71|  3.16k|    for( unsigned int a = 0; a < pScene->mNumMeshes; ++a) {
  ------------------
  |  Branch (71:30): [True: 1.89k, False: 1.27k]
  ------------------
   72|  1.89k|        this->SplitMesh(a, pScene->mMeshes[a],avList);
   73|  1.89k|    }
   74|       |
   75|  1.27k|    if (avList.size() == pScene->mNumMeshes) {
  ------------------
  |  Branch (75:9): [True: 1.27k, False: 0]
  ------------------
   76|  1.27k|        ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Triangle finished. There was nothing to do");
   77|  1.27k|    }
   78|       |
   79|       |    // it seems something has been split. rebuild the mesh list
   80|  1.27k|    delete[] pScene->mMeshes;
   81|  1.27k|    pScene->mNumMeshes = (unsigned int)avList.size();
   82|  1.27k|    pScene->mMeshes = new aiMesh*[avList.size()];
   83|       |
   84|  3.16k|    for (unsigned int i = 0; i < avList.size();++i) {
  ------------------
  |  Branch (84:30): [True: 1.89k, False: 1.27k]
  ------------------
   85|  1.89k|        pScene->mMeshes[i] = avList[i].first;
   86|  1.89k|    }
   87|       |
   88|       |    // now we need to update all nodes
   89|  1.27k|    this->UpdateNode(pScene->mRootNode,avList);
   90|       |    ASSIMP_LOG_INFO("SplitLargeMeshesProcess_Triangle finished. Meshes have been split");
   91|  1.27k|}
_ZN6Assimp32SplitLargeMeshesProcess_Triangle15SetupPropertiesEPKNS_8ImporterE:
   95|  1.27k|void SplitLargeMeshesProcess_Triangle::SetupProperties( const Importer* pImp) {
   96|       |    // get the current value of the split property
   97|  1.27k|    this->LIMIT = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT,AI_SLM_DEFAULT_MAX_TRIANGLES);
   98|  1.27k|}
_ZN6Assimp32SplitLargeMeshesProcess_Triangle10UpdateNodeEP6aiNodeRKNSt3__16vectorINS3_4pairIP6aiMeshjEENS3_9allocatorIS8_EEEE:
  102|  6.46k|void SplitLargeMeshesProcess_Triangle::UpdateNode(aiNode* pcNode, const std::vector<std::pair<aiMesh*, unsigned int> >& avList) {
  103|  6.46k|    if (pcNode == nullptr) {
  ------------------
  |  Branch (103:9): [True: 0, False: 6.46k]
  ------------------
  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.46k|    std::vector<unsigned int> aiEntries;
  110|  6.46k|    aiEntries.reserve(pcNode->mNumMeshes + 1);
  111|  8.47k|    for (unsigned int i = 0; i < pcNode->mNumMeshes;++i) {
  ------------------
  |  Branch (111:30): [True: 2.01k, False: 6.46k]
  ------------------
  112|  5.93k|        for (unsigned int a = 0; a < avList.size();++a) {
  ------------------
  |  Branch (112:34): [True: 3.92k, False: 2.01k]
  ------------------
  113|  3.92k|            if (avList[a].second == pcNode->mMeshes[i]) {
  ------------------
  |  Branch (113:17): [True: 2.01k, False: 1.90k]
  ------------------
  114|  2.01k|                aiEntries.push_back(a);
  115|  2.01k|            }
  116|  3.92k|        }
  117|  2.01k|    }
  118|       |
  119|       |    // now build the new list
  120|  6.46k|    delete[] pcNode->mMeshes;
  121|  6.46k|    pcNode->mNumMeshes = (unsigned int)aiEntries.size();
  122|  6.46k|    pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
  123|       |
  124|  8.47k|    for (unsigned int b = 0; b < pcNode->mNumMeshes;++b) {
  ------------------
  |  Branch (124:30): [True: 2.01k, False: 6.46k]
  ------------------
  125|  2.01k|        pcNode->mMeshes[b] = aiEntries[b];
  126|  2.01k|    }
  127|       |
  128|       |    // recursively update all other nodes
  129|  11.6k|    for (unsigned int i = 0; i < pcNode->mNumChildren;++i) {
  ------------------
  |  Branch (129:30): [True: 5.19k, False: 6.46k]
  ------------------
  130|  5.19k|        UpdateNode ( pcNode->mChildren[i], avList );
  131|  5.19k|    }
  132|  6.46k|}
_ZN6Assimp32SplitLargeMeshesProcess_Triangle9SplitMeshEjP6aiMeshRNSt3__16vectorINS3_4pairIS2_jEENS3_9allocatorIS6_EEEE:
  139|  1.89k|        std::vector<std::pair<aiMesh*, unsigned int> >& avList) {
  140|  1.89k|    if (pMesh->mNumFaces > SplitLargeMeshesProcess_Triangle::LIMIT) {
  ------------------
  |  Branch (140:9): [True: 0, False: 1.89k]
  ------------------
  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|  1.89k|    } else {
  321|  1.89k|        avList.emplace_back(pMesh,a);
  322|  1.89k|    }
  323|  1.89k|}
_ZN6Assimp30SplitLargeMeshesProcess_VertexC2Ev:
  326|  3.24k|SplitLargeMeshesProcess_Vertex::SplitLargeMeshesProcess_Vertex() {
  327|       |    LIMIT = AI_SLM_DEFAULT_MAX_VERTICES;
  328|  3.24k|}
_ZNK6Assimp30SplitLargeMeshesProcess_Vertex8IsActiveEj:
  332|  1.27k|bool SplitLargeMeshesProcess_Vertex::IsActive( unsigned int pFlags) const {
  333|  1.27k|    return (pFlags & aiProcess_SplitLargeMeshes) != 0;
  334|  1.27k|}
_ZN6Assimp30SplitLargeMeshesProcess_Vertex7ExecuteEP7aiScene:
  338|  1.27k|void SplitLargeMeshesProcess_Vertex::Execute( aiScene* pScene) {
  339|  1.27k|    if (0xffffffff == this->LIMIT || nullptr == pScene ) {
  ------------------
  |  Branch (339:9): [True: 0, False: 1.27k]
  |  Branch (339:38): [True: 0, False: 1.27k]
  ------------------
  340|      0|        return;
  341|      0|    }
  342|       |
  343|  1.27k|    ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Vertex begin");
  344|       |
  345|  1.27k|    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.47k|    for (unsigned int a = 0; a < pScene->mNumMeshes; a++) {
  ------------------
  |  Branch (349:30): [True: 1.56k, False: 910]
  ------------------
  350|  1.56k|        if ( pScene->mMeshes[a]->mPrimitiveTypes == aiPrimitiveType_POINT ) {
  ------------------
  |  Branch (350:14): [True: 365, False: 1.20k]
  ------------------
  351|    365|            return;
  352|    365|        }
  353|  1.56k|    }
  354|       |
  355|  2.11k|    for( unsigned int a = 0; a < pScene->mNumMeshes; ++a ) {
  ------------------
  |  Branch (355:30): [True: 1.20k, False: 910]
  ------------------
  356|  1.20k|        this->SplitMesh(a, pScene->mMeshes[a], avList);
  357|  1.20k|    }
  358|       |
  359|    910|    if (avList.size() != pScene->mNumMeshes) {
  ------------------
  |  Branch (359:9): [True: 0, False: 910]
  ------------------
  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|    910|    } else {
  373|       |        ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Vertex finished. There was nothing to do");
  374|    910|    }
  375|    910|}
_ZN6Assimp30SplitLargeMeshesProcess_Vertex15SetupPropertiesEPKNS_8ImporterE:
  379|  1.27k|void SplitLargeMeshesProcess_Vertex::SetupProperties( const Importer* pImp) {
  380|  1.27k|    this->LIMIT = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT,AI_SLM_DEFAULT_MAX_VERTICES);
  381|  1.27k|}
_ZN6Assimp30SplitLargeMeshesProcess_Vertex9SplitMeshEjP6aiMeshRNSt3__16vectorINS3_4pairIS2_jEENS3_9allocatorIS6_EEEE:
  388|  1.20k|        std::vector<std::pair<aiMesh*, unsigned int> >& avList) {
  389|  1.20k|    if (pMesh->mNumVertices > SplitLargeMeshesProcess_Vertex::LIMIT) {
  ------------------
  |  Branch (389:9): [True: 0, False: 1.20k]
  ------------------
  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.20k|    avList.emplace_back(pMesh,a);
  615|  1.20k|}

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

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

_ZNK6Assimp18TriangulateProcess8IsActiveEj:
  179|  1.32k|bool TriangulateProcess::IsActive( unsigned int pFlags) const {
  180|  1.32k|    return (pFlags & aiProcess_Triangulate) != 0;
  181|  1.32k|}
_ZN6Assimp18TriangulateProcess7ExecuteEP7aiScene:
  185|  1.32k|void TriangulateProcess::Execute( aiScene* pScene) {
  186|  1.32k|    ASSIMP_LOG_DEBUG("TriangulateProcess begin");
  187|       |
  188|  1.32k|    bool bHas = false;
  189|  2.50k|    for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
  ------------------
  |  Branch (189:30): [True: 1.17k, False: 1.32k]
  ------------------
  190|  1.17k|    {
  191|  1.17k|        if (pScene->mMeshes[ a ]) {
  ------------------
  |  Branch (191:13): [True: 1.17k, False: 0]
  ------------------
  192|  1.17k|            if ( TriangulateMesh( pScene->mMeshes[ a ] ) ) {
  ------------------
  |  Branch (192:18): [True: 0, False: 1.17k]
  ------------------
  193|      0|                bHas = true;
  194|      0|            }
  195|  1.17k|        }
  196|  1.17k|    }
  197|  1.32k|    if ( bHas ) {
  ------------------
  |  Branch (197:10): [True: 0, False: 1.32k]
  ------------------
  198|      0|        ASSIMP_LOG_INFO( "TriangulateProcess finished. All polygons have been triangulated." );
  199|  1.32k|    } else {
  200|       |        ASSIMP_LOG_DEBUG( "TriangulateProcess finished. There was nothing to be done." );
  201|  1.32k|    }
  202|  1.32k|}
_ZN6Assimp18TriangulateProcess15TriangulateMeshEP6aiMesh:
  206|  1.17k|bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) {
  207|       |    // Now we have aiMesh::mPrimitiveTypes, so this is only here for test cases
  208|  1.17k|    if (!pMesh->mPrimitiveTypes)    {
  ------------------
  |  Branch (208:9): [True: 0, False: 1.17k]
  ------------------
  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.17k|    else if (!(pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON)) {
  ------------------
  |  Branch (221:14): [True: 1.17k, False: 0]
  ------------------
  222|  1.17k|        return false;
  223|  1.17k|    }
  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.24k|    TriangulateProcess() = default;

_ZN6Assimp17ValidateDSProcessC2Ev:
   61|  1.46k|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.46k|void ValidateDSProcess::ReportWarning(const char *msg, ...) {
   85|  2.46k|    ai_assert(nullptr != msg);
   86|       |
   87|  2.46k|    va_list args;
   88|  2.46k|    va_start(args, msg);
   89|       |
   90|  2.46k|    char szBuffer[3000];
   91|  2.46k|    const int iLen = vsnprintf(szBuffer, sizeof(szBuffer), msg, args);
   92|  2.46k|    ai_assert(iLen > 0);
   93|       |
   94|  2.46k|    va_end(args);
   95|       |    ASSIMP_LOG_WARN("Validation warning: ", std::string(szBuffer, iLen));
   96|  2.46k|}
_ZN6Assimp17ValidateDSProcess7ExecuteEP7aiScene:
  183|  1.46k|void ValidateDSProcess::Execute(aiScene *pScene) {
  184|  1.46k|    mScene = pScene;
  185|  1.46k|    ASSIMP_LOG_DEBUG("ValidateDataStructureProcess begin");
  186|       |
  187|       |    // validate the node graph of the scene
  188|  1.46k|    Validate(pScene->mRootNode);
  189|       |
  190|       |    // validate all meshes
  191|  1.46k|    if (pScene->mNumMeshes) {
  ------------------
  |  Branch (191:9): [True: 1.23k, False: 225]
  ------------------
  192|  1.23k|        DoValidation(pScene->mMeshes, pScene->mNumMeshes, "mMeshes", "mNumMeshes");
  193|  1.23k|    } else if (!(mScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE)) {
  ------------------
  |  Branch (193:16): [True: 0, False: 225]
  ------------------
  194|      0|        ReportError("aiScene::mNumMeshes is 0. At least one mesh must be there");
  195|    225|    } else if (pScene->mMeshes) {
  ------------------
  |  Branch (195:16): [True: 0, False: 225]
  ------------------
  196|      0|        ReportError("aiScene::mMeshes is non-null although there are no meshes");
  197|      0|    }
  198|       |
  199|       |    // validate all animations
  200|  1.46k|    if (pScene->mNumAnimations) {
  ------------------
  |  Branch (200:9): [True: 0, False: 1.46k]
  ------------------
  201|      0|        DoValidation(pScene->mAnimations, pScene->mNumAnimations,
  202|      0|                "mAnimations", "mNumAnimations");
  203|  1.46k|    } else if (pScene->mAnimations) {
  ------------------
  |  Branch (203:16): [True: 0, False: 1.46k]
  ------------------
  204|      0|        ReportError("aiScene::mAnimations is non-null although there are no animations");
  205|      0|    }
  206|       |
  207|       |    // validate all cameras
  208|  1.46k|    if (pScene->mNumCameras) {
  ------------------
  |  Branch (208:9): [True: 0, False: 1.46k]
  ------------------
  209|      0|        DoValidationWithNameCheck(pScene->mCameras, pScene->mNumCameras,
  210|      0|                "mCameras", "mNumCameras");
  211|  1.46k|    } else if (pScene->mCameras) {
  ------------------
  |  Branch (211:16): [True: 0, False: 1.46k]
  ------------------
  212|      0|        ReportError("aiScene::mCameras is non-null although there are no cameras");
  213|      0|    }
  214|       |
  215|       |    // validate all lights
  216|  1.46k|    if (pScene->mNumLights) {
  ------------------
  |  Branch (216:9): [True: 0, False: 1.46k]
  ------------------
  217|      0|        DoValidationWithNameCheck(pScene->mLights, pScene->mNumLights,
  218|      0|                "mLights", "mNumLights");
  219|  1.46k|    } else if (pScene->mLights) {
  ------------------
  |  Branch (219:16): [True: 0, False: 1.46k]
  ------------------
  220|      0|        ReportError("aiScene::mLights is non-null although there are no lights");
  221|      0|    }
  222|       |
  223|       |    // validate all textures
  224|  1.46k|    if (pScene->mNumTextures) {
  ------------------
  |  Branch (224:9): [True: 32, False: 1.43k]
  ------------------
  225|     32|        DoValidation(pScene->mTextures, pScene->mNumTextures,
  226|     32|                "mTextures", "mNumTextures");
  227|  1.43k|    } else if (pScene->mTextures) {
  ------------------
  |  Branch (227:16): [True: 0, False: 1.43k]
  ------------------
  228|      0|        ReportError("aiScene::mTextures is non-null although there are no textures");
  229|      0|    }
  230|       |
  231|       |    // validate all materials
  232|  1.46k|    if (pScene->mNumMaterials) {
  ------------------
  |  Branch (232:9): [True: 1.32k, False: 139]
  ------------------
  233|  1.32k|        DoValidation(pScene->mMaterials, pScene->mNumMaterials, "mMaterials", "mNumMaterials");
  234|  1.32k|    }
  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.46k|}
_ZN6Assimp17ValidateDSProcess8ValidateEPK6aiMesh:
  273|  1.23k|void ValidateDSProcess::Validate(const aiMesh *pMesh) {
  274|       |    // validate the material index of the mesh
  275|  1.23k|    if (mScene->mNumMaterials && pMesh->mMaterialIndex >= mScene->mNumMaterials) {
  ------------------
  |  Branch (275:9): [True: 1.23k, False: 0]
  |  Branch (275:34): [True: 0, False: 1.23k]
  ------------------
  276|      0|        ReportError("aiMesh::mMaterialIndex is invalid (value: %i maximum: %i)",
  277|      0|                pMesh->mMaterialIndex, mScene->mNumMaterials - 1);
  278|      0|    }
  279|       |
  280|  1.23k|    Validate(&pMesh->mName);
  281|       |
  282|  26.6k|    for (unsigned int i = 0; i < pMesh->mNumFaces; ++i) {
  ------------------
  |  Branch (282:30): [True: 25.4k, False: 1.23k]
  ------------------
  283|  25.4k|        aiFace &face = pMesh->mFaces[i];
  284|       |
  285|  25.4k|        if (pMesh->mPrimitiveTypes) {
  ------------------
  |  Branch (285:13): [True: 25.4k, False: 0]
  ------------------
  286|  25.4k|            switch (face.mNumIndices) {
  287|      0|            case 0:
  ------------------
  |  Branch (287:13): [True: 0, False: 25.4k]
  ------------------
  288|      0|                ReportError("aiMesh::mFaces[%i].mNumIndices is 0", i);
  289|    724|            case 1:
  ------------------
  |  Branch (289:13): [True: 724, False: 24.7k]
  ------------------
  290|    724|                if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POINT)) {
  ------------------
  |  Branch (290:21): [True: 0, False: 724]
  ------------------
  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|    724|                break;
  296|  3.73k|            case 2:
  ------------------
  |  Branch (296:13): [True: 3.73k, False: 21.7k]
  ------------------
  297|  3.73k|                if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_LINE)) {
  ------------------
  |  Branch (297:21): [True: 0, False: 3.73k]
  ------------------
  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|  3.73k|                break;
  303|  21.0k|            case 3:
  ------------------
  |  Branch (303:13): [True: 21.0k, False: 4.45k]
  ------------------
  304|  21.0k|                if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE)) {
  ------------------
  |  Branch (304:21): [True: 0, False: 21.0k]
  ------------------
  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|  21.0k|                break;
  310|      0|            default:
  ------------------
  |  Branch (310:13): [True: 0, False: 25.4k]
  ------------------
  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|  25.4k|            };
  318|  25.4k|        }
  319|       |
  320|  25.4k|        if (!face.mIndices)
  ------------------
  |  Branch (320:13): [True: 0, False: 25.4k]
  ------------------
  321|      0|            ReportError("aiMesh::mFaces[%i].mIndices is nullptr", i);
  322|  25.4k|    }
  323|       |
  324|       |    // positions must always be there ...
  325|  1.23k|    if (!pMesh->mNumVertices || (!pMesh->mVertices && !mScene->mFlags)) {
  ------------------
  |  Branch (325:9): [True: 11, False: 1.22k]
  |  Branch (325:34): [True: 0, False: 1.22k]
  |  Branch (325:55): [True: 0, False: 0]
  ------------------
  326|     11|        ReportError("The mesh %s contains no vertices", pMesh->mName.C_Str());
  327|     11|    }
  328|       |
  329|  1.23k|    if (pMesh->mNumVertices > AI_MAX_VERTICES) {
  ------------------
  |  Branch (329:9): [True: 0, False: 1.23k]
  ------------------
  330|      0|        ReportError("Mesh has too many vertices: %u, but the limit is %u", pMesh->mNumVertices, AI_MAX_VERTICES);
  331|      0|    }
  332|  1.23k|    if (pMesh->mNumFaces > AI_MAX_FACES) {
  ------------------
  |  Branch (332:9): [True: 0, False: 1.23k]
  ------------------
  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.23k|    if ((pMesh->mTangents != nullptr) != (pMesh->mBitangents != nullptr)) {
  ------------------
  |  Branch (337:9): [True: 0, False: 1.23k]
  ------------------
  338|      0|        ReportError("If there are tangents, bitangent vectors must be present as well");
  339|      0|    }
  340|       |
  341|       |    // faces, too
  342|  1.23k|    if (!pMesh->mNumFaces || (!pMesh->mFaces && !mScene->mFlags)) {
  ------------------
  |  Branch (342:9): [True: 17, False: 1.22k]
  |  Branch (342:31): [True: 0, False: 1.22k]
  |  Branch (342:49): [True: 0, False: 0]
  ------------------
  343|      6|        ReportError("Mesh %s contains no faces", pMesh->mName.C_Str());
  344|      6|    }
  345|       |
  346|       |    // now check whether the face indexing layout is correct:
  347|       |    // unique vertices, pseudo-indexed.
  348|  1.23k|    std::vector<bool> abRefList;
  349|  1.23k|    abRefList.resize(pMesh->mNumVertices, false);
  350|  26.6k|    for (unsigned int i = 0; i < pMesh->mNumFaces; ++i) {
  ------------------
  |  Branch (350:30): [True: 25.4k, False: 1.23k]
  ------------------
  351|  25.4k|        aiFace &face = pMesh->mFaces[i];
  352|  25.4k|        if (face.mNumIndices > AI_MAX_FACE_INDICES) {
  ------------------
  |  Branch (352:13): [True: 0, False: 25.4k]
  ------------------
  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|  96.6k|        for (unsigned int a = 0; a < face.mNumIndices; ++a) {
  ------------------
  |  Branch (356:34): [True: 71.2k, False: 25.4k]
  ------------------
  357|  71.2k|            if (face.mIndices[a] >= pMesh->mNumVertices) {
  ------------------
  |  Branch (357:17): [True: 0, False: 71.2k]
  ------------------
  358|      0|                ReportError("aiMesh::mFaces[%i]::mIndices[%i] is out of range", i, a);
  359|      0|            }
  360|  71.2k|            abRefList[face.mIndices[a]] = true;
  361|  71.2k|        }
  362|  25.4k|    }
  363|       |
  364|       |    // check whether there are vertices that aren't referenced by a face
  365|  1.23k|    bool b = false;
  366|  29.7k|    for (unsigned int i = 0; i < pMesh->mNumVertices; ++i) {
  ------------------
  |  Branch (366:30): [True: 28.5k, False: 1.23k]
  ------------------
  367|  28.5k|        if (!abRefList[i]) b = true;
  ------------------
  |  Branch (367:13): [True: 509, False: 28.0k]
  ------------------
  368|  28.5k|    }
  369|  1.23k|    abRefList.clear();
  370|  1.23k|    if (b) {
  ------------------
  |  Branch (370:9): [True: 259, False: 979]
  ------------------
  371|    259|        ReportWarning("There are unreferenced vertices");
  372|    259|    }
  373|       |
  374|       |    // vertex color channel 2 may not be set if channel 1 is zero ...
  375|  1.23k|    {
  376|  1.23k|        unsigned int i = 0;
  377|  1.49k|        for (; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
  ------------------
  |  Branch (377:16): [True: 1.48k, False: 17]
  ------------------
  378|  1.48k|            if (!pMesh->HasVertexColors(i)) break;
  ------------------
  |  Branch (378:17): [True: 1.22k, False: 260]
  ------------------
  379|  1.48k|        }
  380|  10.7k|        for (; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i)
  ------------------
  |  Branch (380:16): [True: 9.50k, False: 1.23k]
  ------------------
  381|  9.50k|            if (pMesh->HasVertexColors(i)) {
  ------------------
  |  Branch (381:17): [True: 0, False: 9.50k]
  ------------------
  382|      0|                ReportError("Vertex color channel %i is exists "
  383|      0|                            "although the previous channel was nullptr.",
  384|      0|                        i);
  385|      0|            }
  386|  1.23k|    }
  387|       |
  388|       |    // now validate all bones
  389|  1.23k|    if (pMesh->mNumBones) {
  ------------------
  |  Branch (389:9): [True: 235, False: 1.00k]
  ------------------
  390|    235|        if (!pMesh->mBones) {
  ------------------
  |  Branch (390:13): [True: 0, False: 235]
  ------------------
  391|      0|            ReportError("aiMesh::mBones is nullptr (aiMesh::mNumBones is %i)",
  392|      0|                    pMesh->mNumBones);
  393|      0|        }
  394|    235|        std::unique_ptr<float[]> afSum(nullptr);
  395|    235|        if (pMesh->mNumVertices) {
  ------------------
  |  Branch (395:13): [True: 235, False: 0]
  ------------------
  396|    235|            afSum.reset(new float[pMesh->mNumVertices]);
  397|  1.02k|            for (unsigned int i = 0; i < pMesh->mNumVertices; ++i)
  ------------------
  |  Branch (397:38): [True: 789, False: 235]
  ------------------
  398|    789|                afSum[i] = 0.0f;
  399|    235|        }
  400|       |
  401|       |        // check whether there are duplicate bone names
  402|  2.32k|        for (unsigned int i = 0; i < pMesh->mNumBones; ++i) {
  ------------------
  |  Branch (402:34): [True: 2.09k, False: 235]
  ------------------
  403|  2.09k|            const aiBone *bone = pMesh->mBones[i];
  404|  2.09k|            if (bone->mNumWeights > AI_MAX_BONE_WEIGHTS) {
  ------------------
  |  Branch (404:17): [True: 0, False: 2.09k]
  ------------------
  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|  2.09k|            if (!pMesh->mBones[i]) {
  ------------------
  |  Branch (408:17): [True: 0, False: 2.09k]
  ------------------
  409|      0|                ReportError("aiMesh::mBones[%i] is nullptr (aiMesh::mNumBones is %i)",
  410|      0|                        i, pMesh->mNumBones);
  411|      0|            }
  412|  2.09k|            Validate(pMesh, pMesh->mBones[i], afSum.get());
  413|       |
  414|  11.5k|            for (unsigned int a = i + 1; a < pMesh->mNumBones; ++a) {
  ------------------
  |  Branch (414:42): [True: 9.48k, False: 2.09k]
  ------------------
  415|  9.48k|                if (pMesh->mBones[i]->mName == pMesh->mBones[a]->mName) {
  ------------------
  |  Branch (415:21): [True: 31, False: 9.45k]
  ------------------
  416|     31|                    const char *name = "unknown";
  417|     31|                    if (nullptr != pMesh->mBones[i]->mName.C_Str()) {
  ------------------
  |  Branch (417:25): [True: 31, False: 0]
  ------------------
  418|     31|                        name = pMesh->mBones[i]->mName.C_Str();
  419|     31|                    }
  420|     31|                    ReportError("aiMesh::mBones[%i], name = \"%s\" has the same name as "
  421|     31|                                "aiMesh::mBones[%i]",
  422|     31|                            i, name, a);
  423|     31|                }
  424|  9.48k|            }
  425|  2.09k|        }
  426|       |        // check whether all bone weights for a vertex sum to 1.0 ...
  427|    904|        for (unsigned int i = 0; i < pMesh->mNumVertices; ++i) {
  ------------------
  |  Branch (427:34): [True: 669, False: 235]
  ------------------
  428|    669|            if (afSum[i] && (afSum[i] <= 0.94 || afSum[i] >= 1.05)) {
  ------------------
  |  Branch (428:17): [True: 586, False: 83]
  |  Branch (428:30): [True: 160, False: 426]
  |  Branch (428:50): [True: 345, False: 81]
  ------------------
  429|    505|                ReportWarning("aiMesh::mVertices[%i]: bone weight sum != 1.0 (sum is %f)", i, afSum[i]);
  430|    505|            }
  431|    669|        }
  432|  1.00k|    } else if (pMesh->mBones) {
  ------------------
  |  Branch (432:16): [True: 4, False: 999]
  ------------------
  433|      4|        ReportError("aiMesh::mBones is non-null although there are no bones");
  434|      4|    }
  435|  1.23k|}
_ZN6Assimp17ValidateDSProcess8ValidateEPK6aiMeshPK6aiBonePf:
  438|  2.09k|void ValidateDSProcess::Validate(const aiMesh *pMesh, const aiBone *pBone, float *afSum) {
  439|  2.09k|    this->Validate(&pBone->mName);
  440|       |
  441|  2.09k|    if (!pBone->mNumWeights) {
  ------------------
  |  Branch (441:9): [True: 0, False: 2.09k]
  ------------------
  442|      0|        ReportWarning("aiBone::mNumWeights is zero");
  443|      0|    }
  444|       |
  445|       |    // check whether all vertices affected by this bone are valid
  446|  6.50k|    for (unsigned int i = 0; i < pBone->mNumWeights; ++i) {
  ------------------
  |  Branch (446:30): [True: 4.41k, False: 2.09k]
  ------------------
  447|  4.41k|        if (pBone->mWeights[i].mVertexId >= pMesh->mNumVertices) {
  ------------------
  |  Branch (447:13): [True: 3, False: 4.40k]
  ------------------
  448|      3|            ReportError("aiBone::mWeights[%i].mVertexId is out of range", i);
  449|  4.40k|        } else if (!pBone->mWeights[i].mWeight || pBone->mWeights[i].mWeight > 1.0f) {
  ------------------
  |  Branch (449:20): [True: 920, False: 3.48k]
  |  Branch (449:51): [True: 765, False: 2.72k]
  ------------------
  450|  1.68k|                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.68k|        }
  452|  4.41k|        afSum[pBone->mWeights[i].mVertexId] += pBone->mWeights[i].mWeight;
  453|  4.41k|    }
  454|  2.09k|}
_ZN6Assimp17ValidateDSProcess24SearchForInvalidTexturesEPK10aiMaterial13aiTextureType:
  491|  38.8k|        aiTextureType type) {
  492|  38.8k|    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|  38.8k|    int iNumIndices = 0;
  501|  38.8k|    int iIndex = -1;
  502|   489k|    for (unsigned int i = 0; i < pMaterial->mNumProperties; ++i) {
  ------------------
  |  Branch (502:30): [True: 450k, False: 38.8k]
  ------------------
  503|   450k|        aiMaterialProperty *prop = pMaterial->mProperties[i];
  504|   450k|        ai_assert(nullptr != prop);
  505|   450k|        if (!::strcmp(prop->mKey.data, "$tex.file") && prop->mSemantic == static_cast<unsigned int>(type)) {
  ------------------
  |  Branch (505:13): [True: 986, False: 449k]
  |  Branch (505:56): [True: 58, False: 928]
  ------------------
  506|     58|            iIndex = std::max(iIndex, (int)prop->mIndex);
  507|     58|            ++iNumIndices;
  508|       |
  509|     58|            if (aiPTI_String != prop->mType) {
  ------------------
  |  Branch (509:17): [True: 0, False: 58]
  ------------------
  510|      0|                ReportError("Material property %s is expected to be a string", prop->mKey.data);
  511|      0|            }
  512|     58|        }
  513|   450k|    }
  514|  38.8k|    if (iIndex + 1 != iNumIndices) {
  ------------------
  |  Branch (514:9): [True: 0, False: 38.8k]
  ------------------
  515|      0|        ReportError("%s #%i is set, but there are only %i %s textures",
  516|      0|                szType, iIndex, iNumIndices, szType);
  517|      0|    }
  518|  38.8k|    if (!iNumIndices) {
  ------------------
  |  Branch (518:9): [True: 38.8k, False: 58]
  ------------------
  519|  38.8k|        return;
  520|  38.8k|    }
  521|     58|    std::vector<aiTextureMapping> mappings(iNumIndices);
  522|       |
  523|       |    // Now check whether all UV indices are valid ...
  524|     58|    bool bNoSpecified = true;
  525|  1.53k|    for (unsigned int i = 0; i < pMaterial->mNumProperties; ++i) {
  ------------------
  |  Branch (525:30): [True: 1.48k, False: 58]
  ------------------
  526|  1.48k|        aiMaterialProperty *prop = pMaterial->mProperties[i];
  527|  1.48k|        if (static_cast<aiTextureType>(prop->mSemantic) != type) {
  ------------------
  |  Branch (527:13): [True: 1.08k, False: 394]
  ------------------
  528|  1.08k|            continue;
  529|  1.08k|        }
  530|       |
  531|    394|        if ((int)prop->mIndex >= iNumIndices) {
  ------------------
  |  Branch (531:13): [True: 0, False: 394]
  ------------------
  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|    394|        if (!::strcmp(prop->mKey.data, "$tex.mapping")) {
  ------------------
  |  Branch (537:13): [True: 0, False: 394]
  ------------------
  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|    394|        } else if (!::strcmp(prop->mKey.data, "$tex.uvtrafo")) {
  ------------------
  |  Branch (543:20): [True: 0, False: 394]
  ------------------
  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|    394|        } else if (!::strcmp(prop->mKey.data, "$tex.uvwsrc")) {
  ------------------
  |  Branch (549:20): [True: 58, False: 336]
  ------------------
  550|     58|            if (aiPTI_Integer != prop->mType || sizeof(int) > prop->mDataLength) {
  ------------------
  |  Branch (550:17): [True: 0, False: 58]
  |  Branch (550:49): [True: 0, False: 58]
  ------------------
  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|     58|            bNoSpecified = false;
  555|       |
  556|       |            // Ignore UV indices for texture channels that are not there ...
  557|       |
  558|       |            // Get the value
  559|     58|            iIndex = *((unsigned int *)prop->mData);
  560|       |
  561|       |            // Check whether there is a mesh using this material
  562|       |            // which has not enough UV channels ...
  563|    116|            for (unsigned int a = 0; a < mScene->mNumMeshes; ++a) {
  ------------------
  |  Branch (563:38): [True: 58, False: 58]
  ------------------
  564|     58|                aiMesh *mesh = this->mScene->mMeshes[a];
  565|     58|                if (mesh->mMaterialIndex == (unsigned int)i) {
  ------------------
  |  Branch (565:21): [True: 0, False: 58]
  ------------------
  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|     58|            }
  575|     58|        }
  576|    394|    }
  577|     58|    if (bNoSpecified) {
  ------------------
  |  Branch (577:9): [True: 0, False: 58]
  ------------------
  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|     58|}
_ZN6Assimp17ValidateDSProcess8ValidateEPK10aiMaterial:
  593|  2.28k|void ValidateDSProcess::Validate(const aiMaterial *pMaterial) {
  594|       |    // check whether there are material keys that are obviously not legal
  595|  28.7k|    for (unsigned int i = 0; i < pMaterial->mNumProperties; ++i) {
  ------------------
  |  Branch (595:30): [True: 26.4k, False: 2.28k]
  ------------------
  596|  26.4k|        const aiMaterialProperty *prop = pMaterial->mProperties[i];
  597|  26.4k|        if (!prop) {
  ------------------
  |  Branch (597:13): [True: 0, False: 26.4k]
  ------------------
  598|      0|            ReportError("aiMaterial::mProperties[%i] is nullptr (aiMaterial::mNumProperties is %i)",
  599|      0|                    i, pMaterial->mNumProperties);
  600|      0|        }
  601|  26.4k|        if (!prop->mDataLength || !prop->mData) {
  ------------------
  |  Branch (601:13): [True: 0, False: 26.4k]
  |  Branch (601:35): [True: 0, False: 26.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|  26.4k|        if (aiPTI_String == prop->mType) {
  ------------------
  |  Branch (607:13): [True: 3.37k, False: 23.1k]
  ------------------
  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.37k|            if (prop->mDataLength < 5 || prop->mDataLength < 4 + (*reinterpret_cast<uint32_t *>(prop->mData)) + 1) {
  ------------------
  |  Branch (610:17): [True: 0, False: 3.37k]
  |  Branch (610:42): [True: 0, False: 3.37k]
  ------------------
  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.37k|            if (prop->mData[prop->mDataLength - 1]) {
  ------------------
  |  Branch (615:17): [True: 0, False: 3.37k]
  ------------------
  616|      0|                ReportError("Missing null-terminator in string material property");
  617|      0|            }
  618|       |            //  Validate((const aiString*)prop->mData);
  619|  23.1k|        } else if (aiPTI_Float == prop->mType) {
  ------------------
  |  Branch (619:20): [True: 18.3k, False: 4.80k]
  ------------------
  620|  18.3k|            if (prop->mDataLength < sizeof(float)) {
  ------------------
  |  Branch (620:17): [True: 0, False: 18.3k]
  ------------------
  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|  18.3k|        } else if (aiPTI_Integer == prop->mType) {
  ------------------
  |  Branch (625:20): [True: 58, False: 4.74k]
  ------------------
  626|     58|            if (prop->mDataLength < sizeof(int)) {
  ------------------
  |  Branch (626:17): [True: 0, False: 58]
  ------------------
  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|     58|        }
  632|       |        // TODO: check whether there is a key with an unknown name ...
  633|  26.4k|    }
  634|       |
  635|       |    // make some more specific tests
  636|  2.28k|    ai_real fTemp;
  637|  2.28k|    int iShading;
  638|  2.28k|    if (AI_SUCCESS == aiGetMaterialInteger(pMaterial, AI_MATKEY_SHADING_MODEL, &iShading)) {
  ------------------
  |  Branch (638:9): [True: 2.28k, False: 0]
  ------------------
  639|  2.28k|        switch ((aiShadingMode)iShading) {
  640|      0|        case aiShadingMode_Blinn:
  ------------------
  |  Branch (640:9): [True: 0, False: 2.28k]
  ------------------
  641|      0|        case aiShadingMode_CookTorrance:
  ------------------
  |  Branch (641:9): [True: 0, False: 2.28k]
  ------------------
  642|      0|        case aiShadingMode_Phong:
  ------------------
  |  Branch (642:9): [True: 0, False: 2.28k]
  ------------------
  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.28k|        default:
  ------------------
  |  Branch (653:9): [True: 2.28k, False: 0]
  ------------------
  654|  2.28k|            break;
  655|  2.28k|        }
  656|  2.28k|    }
  657|       |
  658|  2.28k|    if (AI_SUCCESS == aiGetMaterialFloat(pMaterial, AI_MATKEY_OPACITY, &fTemp) && (!fTemp || fTemp > 1.01)) {
  ------------------
  |  Branch (658:9): [True: 2.28k, False: 0]
  |  Branch (658:84): [True: 8, False: 2.28k]
  |  Branch (658:94): [True: 6, False: 2.27k]
  ------------------
  659|     14|        ReportWarning("Invalid opacity value (must be 0 < opacity < 1.0)");
  660|     14|    }
  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.28k|    SearchForInvalidTextures(pMaterial, aiTextureType_DIFFUSE);
  666|  2.28k|    SearchForInvalidTextures(pMaterial, aiTextureType_SPECULAR);
  667|  2.28k|    SearchForInvalidTextures(pMaterial, aiTextureType_AMBIENT);
  668|  2.28k|    SearchForInvalidTextures(pMaterial, aiTextureType_EMISSIVE);
  669|  2.28k|    SearchForInvalidTextures(pMaterial, aiTextureType_OPACITY);
  670|  2.28k|    SearchForInvalidTextures(pMaterial, aiTextureType_SHININESS);
  671|  2.28k|    SearchForInvalidTextures(pMaterial, aiTextureType_HEIGHT);
  672|  2.28k|    SearchForInvalidTextures(pMaterial, aiTextureType_NORMALS);
  673|  2.28k|    SearchForInvalidTextures(pMaterial, aiTextureType_DISPLACEMENT);
  674|  2.28k|    SearchForInvalidTextures(pMaterial, aiTextureType_LIGHTMAP);
  675|  2.28k|    SearchForInvalidTextures(pMaterial, aiTextureType_REFLECTION);
  676|  2.28k|    SearchForInvalidTextures(pMaterial, aiTextureType_BASE_COLOR);
  677|  2.28k|    SearchForInvalidTextures(pMaterial, aiTextureType_NORMAL_CAMERA);
  678|  2.28k|    SearchForInvalidTextures(pMaterial, aiTextureType_EMISSION_COLOR);
  679|  2.28k|    SearchForInvalidTextures(pMaterial, aiTextureType_METALNESS);
  680|  2.28k|    SearchForInvalidTextures(pMaterial, aiTextureType_DIFFUSE_ROUGHNESS);
  681|  2.28k|    SearchForInvalidTextures(pMaterial, aiTextureType_AMBIENT_OCCLUSION);
  682|  2.28k|}
_ZN6Assimp17ValidateDSProcess8ValidateEPK9aiTexture:
  685|     32|void ValidateDSProcess::Validate(const aiTexture *pTexture) {
  686|       |    // the data section may NEVER be nullptr
  687|     32|    if (nullptr == pTexture->pcData) {
  ------------------
  |  Branch (687:9): [True: 0, False: 32]
  ------------------
  688|      0|        ReportError("aiTexture::pcData is nullptr");
  689|      0|    }
  690|     32|    if (pTexture->mHeight) {
  ------------------
  |  Branch (690:9): [True: 0, False: 32]
  ------------------
  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|     32|    } else {
  696|     32|        if (!pTexture->mWidth) {
  ------------------
  |  Branch (696:13): [True: 0, False: 32]
  ------------------
  697|      0|            ReportError("aiTexture::mWidth is zero (compressed texture)");
  698|      0|        }
  699|     32|        if ('\0' != pTexture->achFormatHint[HINTMAXTEXTURELEN - 1]) {
  ------------------
  |  Branch (699:13): [True: 0, False: 32]
  ------------------
  700|      0|            ReportWarning("aiTexture::achFormatHint must be zero-terminated");
  701|     32|        } else if ('.' == pTexture->achFormatHint[0]) {
  ------------------
  |  Branch (701:20): [True: 1, False: 31]
  ------------------
  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|     32|    }
  707|       |
  708|     32|    const char *sz = pTexture->achFormatHint;
  709|     32|    if ((sz[0] >= 'A' && sz[0] <= 'Z') ||
  ------------------
  |  Branch (709:10): [True: 28, False: 4]
  |  Branch (709:26): [True: 2, False: 26]
  ------------------
  710|     30|            (sz[1] >= 'A' && sz[1] <= 'Z') ||
  ------------------
  |  Branch (710:14): [True: 28, False: 2]
  |  Branch (710:30): [True: 1, False: 27]
  ------------------
  711|     29|            (sz[2] >= 'A' && sz[2] <= 'Z') ||
  ------------------
  |  Branch (711:14): [True: 27, False: 2]
  |  Branch (711:30): [True: 1, False: 26]
  ------------------
  712|     28|            (sz[3] >= 'A' && sz[3] <= 'Z')) {
  ------------------
  |  Branch (712:14): [True: 0, False: 28]
  |  Branch (712:30): [True: 0, False: 0]
  ------------------
  713|      4|        ReportError("aiTexture::achFormatHint contains non-lowercase letters");
  714|      4|    }
  715|     32|}
_ZN6Assimp17ValidateDSProcess8ValidateEPK6aiNode:
  850|  7.68k|void ValidateDSProcess::Validate(const aiNode *pNode) {
  851|  7.68k|    if (!pNode) {
  ------------------
  |  Branch (851:9): [True: 80, False: 7.60k]
  ------------------
  852|     80|        ReportError("A node of the scene-graph is nullptr");
  853|     80|    }
  854|       |    // Validate node name string first so that it's safe to use in below expressions
  855|  7.68k|    this->Validate(&pNode->mName);
  856|  7.68k|    const char *nodeName = (&pNode->mName)->C_Str();
  857|  7.68k|    if (pNode != mScene->mRootNode && !pNode->mParent) {
  ------------------
  |  Branch (857:9): [True: 6.22k, False: 1.46k]
  |  Branch (857:39): [True: 0, False: 6.22k]
  ------------------
  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.68k|    if (pNode->mNumMeshes) {
  ------------------
  |  Branch (862:9): [True: 1.30k, False: 6.37k]
  ------------------
  863|  1.30k|        if (!pNode->mMeshes) {
  ------------------
  |  Branch (863:13): [True: 0, False: 1.30k]
  ------------------
  864|      0|            ReportError("aiNode::mMeshes is nullptr for node %s (aiNode::mNumMeshes is %i)",
  865|      0|                    nodeName, pNode->mNumMeshes);
  866|      0|        }
  867|  1.30k|        std::vector<bool> abHadMesh;
  868|  1.30k|        abHadMesh.resize(mScene->mNumMeshes, false);
  869|  2.61k|        for (unsigned int i = 0; i < pNode->mNumMeshes; ++i) {
  ------------------
  |  Branch (869:34): [True: 1.30k, False: 1.30k]
  ------------------
  870|  1.30k|            if (pNode->mMeshes[i] >= mScene->mNumMeshes) {
  ------------------
  |  Branch (870:17): [True: 0, False: 1.30k]
  ------------------
  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.30k|            if (abHadMesh[pNode->mMeshes[i]]) {
  ------------------
  |  Branch (874:17): [True: 0, False: 1.30k]
  ------------------
  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.30k|            abHadMesh[pNode->mMeshes[i]] = true;
  879|  1.30k|        }
  880|  1.30k|    }
  881|  7.68k|    if (pNode->mNumChildren) {
  ------------------
  |  Branch (881:9): [True: 3.71k, False: 3.96k]
  ------------------
  882|  3.71k|        if (!pNode->mChildren) {
  ------------------
  |  Branch (882:13): [True: 0, False: 3.71k]
  ------------------
  883|      0|            ReportError("aiNode::mChildren is nullptr for node %s (aiNode::mNumChildren is %i)",
  884|      0|                    nodeName, pNode->mNumChildren);
  885|      0|        }
  886|  9.93k|        for (unsigned int i = 0; i < pNode->mNumChildren; ++i) {
  ------------------
  |  Branch (886:34): [True: 6.22k, False: 3.71k]
  ------------------
  887|  6.22k|            const aiNode *pChild = pNode->mChildren[i];
  888|  6.22k|            Validate(pChild);
  889|  6.22k|            if (pChild->mParent != pNode) {
  ------------------
  |  Branch (889:17): [True: 0, False: 6.22k]
  ------------------
  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.22k|        }
  894|  3.96k|    } else if (pNode->mChildren) {
  ------------------
  |  Branch (894:16): [True: 0, False: 3.96k]
  ------------------
  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.68k|}
_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|   120k|    while (true) {
  ------------------
  |  Branch (907:12): [True: 120k, Folded]
  ------------------
  908|   120k|        if ('\0' == *sz) {
  ------------------
  |  Branch (908:13): [True: 10.9k, False: 109k]
  ------------------
  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|   109k|        } else if (sz >= &pString->data[AI_MAXLEN]) {
  ------------------
  |  Branch (913:20): [True: 0, False: 109k]
  ------------------
  914|      0|            ReportError("aiString::data is invalid. There is no terminal character");
  915|      0|        }
  916|   109k|        ++sz;
  917|   109k|    }
  918|  10.9k|}
_ZN6Assimp17ValidateDSProcess12DoValidationI6aiMeshEEvPPT_jPKcS7_:
  109|  1.23k|inline void ValidateDSProcess::DoValidation(T **parray, unsigned int size, const char *firstName, const char *secondName) {
  110|       |    // validate all entries
  111|  1.23k|    if (size == 0) {
  ------------------
  |  Branch (111:9): [True: 0, False: 1.23k]
  ------------------
  112|      0|        return;
  113|      0|    }
  114|       |
  115|  1.23k|    if (!parray) {
  ------------------
  |  Branch (115:9): [True: 0, False: 1.23k]
  ------------------
  116|      0|        ReportError("aiScene::%s is nullptr (aiScene::%s is %i)",
  117|      0|                firstName, secondName, size);
  118|      0|    }
  119|       |
  120|  2.47k|    for (unsigned int i = 0; i < size; ++i) {
  ------------------
  |  Branch (120:30): [True: 1.23k, False: 1.23k]
  ------------------
  121|  1.23k|        if (!parray[i]) {
  ------------------
  |  Branch (121:13): [True: 0, False: 1.23k]
  ------------------
  122|      0|            ReportError("aiScene::%s[%i] is nullptr (aiScene::%s is %i)",
  123|      0|                    firstName, i, secondName, size);
  124|      0|        }
  125|  1.23k|        Validate(parray[i]);
  126|  1.23k|    }
  127|  1.23k|}
_ZN6Assimp17ValidateDSProcess12DoValidationI9aiTextureEEvPPT_jPKcS7_:
  109|     32|inline void ValidateDSProcess::DoValidation(T **parray, unsigned int size, const char *firstName, const char *secondName) {
  110|       |    // validate all entries
  111|     32|    if (size == 0) {
  ------------------
  |  Branch (111:9): [True: 0, False: 32]
  ------------------
  112|      0|        return;
  113|      0|    }
  114|       |
  115|     32|    if (!parray) {
  ------------------
  |  Branch (115:9): [True: 0, False: 32]
  ------------------
  116|      0|        ReportError("aiScene::%s is nullptr (aiScene::%s is %i)",
  117|      0|                firstName, secondName, size);
  118|      0|    }
  119|       |
  120|     64|    for (unsigned int i = 0; i < size; ++i) {
  ------------------
  |  Branch (120:30): [True: 32, False: 32]
  ------------------
  121|     32|        if (!parray[i]) {
  ------------------
  |  Branch (121:13): [True: 0, False: 32]
  ------------------
  122|      0|            ReportError("aiScene::%s[%i] is nullptr (aiScene::%s is %i)",
  123|      0|                    firstName, i, secondName, size);
  124|      0|        }
  125|     32|        Validate(parray[i]);
  126|     32|    }
  127|     32|}
_ZN6Assimp17ValidateDSProcess12DoValidationI10aiMaterialEEvPPT_jPKcS7_:
  109|  1.32k|inline void ValidateDSProcess::DoValidation(T **parray, unsigned int size, const char *firstName, const char *secondName) {
  110|       |    // validate all entries
  111|  1.32k|    if (size == 0) {
  ------------------
  |  Branch (111:9): [True: 0, False: 1.32k]
  ------------------
  112|      0|        return;
  113|      0|    }
  114|       |
  115|  1.32k|    if (!parray) {
  ------------------
  |  Branch (115:9): [True: 0, False: 1.32k]
  ------------------
  116|      0|        ReportError("aiScene::%s is nullptr (aiScene::%s is %i)",
  117|      0|                firstName, secondName, size);
  118|      0|    }
  119|       |
  120|  3.61k|    for (unsigned int i = 0; i < size; ++i) {
  ------------------
  |  Branch (120:30): [True: 2.28k, False: 1.32k]
  ------------------
  121|  2.28k|        if (!parray[i]) {
  ------------------
  |  Branch (121:13): [True: 0, False: 2.28k]
  ------------------
  122|      0|            ReportError("aiScene::%s[%i] is nullptr (aiScene::%s is %i)",
  123|      0|                    firstName, i, secondName, size);
  124|      0|        }
  125|  2.28k|        Validate(parray[i]);
  126|  2.28k|    }
  127|  1.32k|}

_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.48k|	PUGI_IMPL_FN xml_node::xml_node(): _root(nullptr)
 5594|  6.48k|	{
 5595|  6.48k|	}
_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|  14.3k|    void* Malloc(size_t size) { 
   87|  14.3k|        if (size) //  behavior of malloc(0) is implementation defined.
  ------------------
  |  Branch (87:13): [True: 14.3k, False: 0]
  ------------------
   88|  14.3k|            return RAPIDJSON_MALLOC(size);
  ------------------
  |  |  696|  14.3k|#define RAPIDJSON_MALLOC(size) std::malloc(size)
  ------------------
   89|      0|        else
   90|      0|            return NULL; // standardize to returning NULL.
   91|  14.3k|    }
_ZN9rapidjson12CrtAllocator7ReallocEPvmm:
   92|  21.3k|    void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
   93|  21.3k|        (void)originalSize;
   94|  21.3k|        if (newSize == 0) {
  ------------------
  |  Branch (94:13): [True: 0, False: 21.3k]
  ------------------
   95|      0|            RAPIDJSON_FREE(originalPtr);
  ------------------
  |  |  704|      0|#define RAPIDJSON_FREE(ptr) std::free(ptr)
  ------------------
   96|      0|            return NULL;
   97|      0|        }
   98|  21.3k|        return RAPIDJSON_REALLOC(originalPtr, newSize);
  ------------------
  |  |  700|  21.3k|#define RAPIDJSON_REALLOC(ptr, new_size) std::realloc(ptr, new_size)
  ------------------
   99|  21.3k|    }
_ZN9rapidjson12CrtAllocator4FreeEPv:
  100|  38.5k|    static void Free(void *ptr) RAPIDJSON_NOEXCEPT { RAPIDJSON_FREE(ptr); }
  ------------------
  |  |  704|  38.5k|#define RAPIDJSON_FREE(ptr) std::free(ptr)
  ------------------
_ZN9rapidjson19MemoryPoolAllocatorINS_12CrtAllocatorEE12GetChunkHeadEPNS2_10SharedDataE:
  151|  8.06k|    {
  152|  8.06k|        return reinterpret_cast<ChunkHeader*>(reinterpret_cast<uint8_t*>(shared) + SIZEOF_SHARED_DATA);
  153|  8.06k|    }
_ZN9rapidjson19MemoryPoolAllocatorINS_12CrtAllocatorEE5ClearEv:
  277|  8.06k|    void Clear() RAPIDJSON_NOEXCEPT {
  278|  8.06k|        RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
  ------------------
  |  |  687|  8.06k|#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
  |  |  ------------------
  |  |  |  |  437|  8.06k|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  ------------------
  ------------------
  |  Branch (278:9): [True: 8.06k, False: 0]
  ------------------
  279|  14.3k|        for (;;) {
  280|  14.3k|            ChunkHeader* c = shared_->chunkHead;
  281|  14.3k|            if (!c->next) {
  ------------------
  |  Branch (281:17): [True: 8.06k, False: 6.27k]
  ------------------
  282|  8.06k|                break;
  283|  8.06k|            }
  284|  6.27k|            shared_->chunkHead = c->next;
  285|  6.27k|            baseAllocator_->Free(c);
  286|  6.27k|        }
  287|  8.06k|        shared_->chunkHead->size = 0;
  288|  8.06k|    }
_ZN9rapidjson19MemoryPoolAllocatorINS_12CrtAllocatorEE6MallocEm:
  321|  1.13M|    void* Malloc(size_t size) {
  322|  1.13M|        RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
  ------------------
  |  |  687|  1.13M|#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
  |  |  ------------------
  |  |  |  |  437|  1.13M|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  ------------------
  ------------------
  |  Branch (322:9): [True: 1.13M, False: 0]
  ------------------
  323|  1.13M|        if (!size)
  ------------------
  |  Branch (323:13): [True: 0, False: 1.13M]
  ------------------
  324|      0|            return NULL;
  325|       |
  326|  1.13M|        size = RAPIDJSON_ALIGN(size);
  ------------------
  |  |  307|  1.13M|#define RAPIDJSON_ALIGN(x) (((x) + static_cast<size_t>(7u)) & ~static_cast<size_t>(7u))
  ------------------
  327|  1.13M|        if (RAPIDJSON_UNLIKELY(shared_->chunkHead->size + size > shared_->chunkHead->capacity))
  ------------------
  |  |  505|  1.13M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 6.27k, False: 1.13M]
  |  |  ------------------
  ------------------
  328|  6.27k|            if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size))
  ------------------
  |  Branch (328:17): [True: 0, False: 6.27k]
  |  Branch (328:27): [True: 6.15k, False: 128]
  ------------------
  329|      0|                return NULL;
  330|       |
  331|  1.13M|        void *buffer = GetChunkBuffer(shared_) + shared_->chunkHead->size;
  332|  1.13M|        shared_->chunkHead->size += size;
  333|  1.13M|        return buffer;
  334|  1.13M|    }
_ZN9rapidjson19MemoryPoolAllocatorINS_12CrtAllocatorEE8AddChunkEm:
  390|  6.27k|    bool AddChunk(size_t capacity) {
  391|  6.27k|        if (!baseAllocator_)
  ------------------
  |  Branch (391:13): [True: 0, False: 6.27k]
  ------------------
  392|      0|            shared_->ownBaseAllocator = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)();
  ------------------
  |  |  712|      0|#define RAPIDJSON_NEW(TypeName) new TypeName
  ------------------
  393|  6.27k|        if (ChunkHeader* chunk = static_cast<ChunkHeader*>(baseAllocator_->Malloc(SIZEOF_CHUNK_HEADER + capacity))) {
  ------------------
  |  Branch (393:26): [True: 6.27k, False: 0]
  ------------------
  394|  6.27k|            chunk->capacity = capacity;
  395|  6.27k|            chunk->size = 0;
  396|  6.27k|            chunk->next = shared_->chunkHead;
  397|  6.27k|            shared_->chunkHead = chunk;
  398|  6.27k|            return true;
  399|  6.27k|        }
  400|      0|        else
  401|      0|            return false;
  402|  6.27k|    }
_ZN9rapidjson19MemoryPoolAllocatorINS_12CrtAllocatorEE14GetChunkBufferEPNS2_10SharedDataE:
  155|  1.13M|    {
  156|  1.13M|        return reinterpret_cast<uint8_t*>(shared->chunkHead) + SIZEOF_CHUNK_HEADER;
  157|  1.13M|    }
_ZN9rapidjson6MallocINS_13GenericMemberINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEES6_EEPT_RT0_m:
  443|   913k|{
  444|       |    return Realloc<T, A>(a, NULL, 0, n);
  445|   913k|}
_ZN9rapidjson7ReallocINS_13GenericMemberINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEES6_EEPT_RT0_S9_mm:
  436|   913k|{
  437|   913k|    RAPIDJSON_NOEXCEPT_ASSERT(old_n <= (std::numeric_limits<size_t>::max)() / sizeof(T) && new_n <= (std::numeric_limits<size_t>::max)() / sizeof(T));
  ------------------
  |  |  687|   913k|#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
  |  |  ------------------
  |  |  |  |  437|   913k|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  ------------------
  ------------------
  |  Branch (437:5): [True: 913k, False: 0]
  |  Branch (437:5): [True: 913k, False: 0]
  |  Branch (437:5): [True: 913k, False: 0]
  ------------------
  438|   913k|    return static_cast<T*>(a.Realloc(old_p, old_n * sizeof(T), new_n * sizeof(T)));
  439|   913k|}
_ZN9rapidjson19MemoryPoolAllocatorINS_12CrtAllocatorEE7ReallocEPvmm:
  337|   913k|    void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
  338|   913k|        if (originalPtr == 0)
  ------------------
  |  Branch (338:13): [True: 913k, False: 0]
  ------------------
  339|   913k|            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.06k|        chunk_capacity_(chunkSize),
  172|  8.06k|        baseAllocator_(baseAllocator ? baseAllocator : RAPIDJSON_NEW(BaseAllocator)()),
  ------------------
  |  |  712|  8.06k|#define RAPIDJSON_NEW(TypeName) new TypeName
  ------------------
  |  Branch (172:24): [True: 0, False: 8.06k]
  ------------------
  173|  8.06k|        shared_(static_cast<SharedData*>(baseAllocator_ ? baseAllocator_->Malloc(SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER) : 0))
  ------------------
  |  Branch (173:42): [True: 8.06k, False: 0]
  ------------------
  174|  8.06k|    {
  175|  8.06k|        RAPIDJSON_ASSERT(baseAllocator_ != 0);
  ------------------
  |  |  437|  8.06k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (175:9): [True: 8.06k, False: 0]
  ------------------
  176|  8.06k|        RAPIDJSON_ASSERT(shared_ != 0);
  ------------------
  |  |  437|  8.06k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (176:9): [True: 8.06k, False: 0]
  ------------------
  177|  8.06k|        if (baseAllocator) {
  ------------------
  |  Branch (177:13): [True: 0, False: 8.06k]
  ------------------
  178|      0|            shared_->ownBaseAllocator = 0;
  179|      0|        }
  180|  8.06k|        else {
  181|  8.06k|            shared_->ownBaseAllocator = baseAllocator_;
  182|  8.06k|        }
  183|  8.06k|        shared_->chunkHead = GetChunkHead(shared_);
  184|  8.06k|        shared_->chunkHead->capacity = 0;
  185|  8.06k|        shared_->chunkHead->size = 0;
  186|  8.06k|        shared_->chunkHead->next = 0;
  187|  8.06k|        shared_->ownBuffer = true;
  188|  8.06k|        shared_->refcount = 1;
  189|  8.06k|    }
_ZN9rapidjson19MemoryPoolAllocatorINS_12CrtAllocatorEED2Ev:
  259|  8.06k|    ~MemoryPoolAllocator() RAPIDJSON_NOEXCEPT {
  260|  8.06k|        if (!shared_) {
  ------------------
  |  Branch (260:13): [True: 0, False: 8.06k]
  ------------------
  261|       |            // do nothing if moved
  262|      0|            return;
  263|      0|        }
  264|  8.06k|        if (shared_->refcount > 1) {
  ------------------
  |  Branch (264:13): [True: 0, False: 8.06k]
  ------------------
  265|      0|            --shared_->refcount;
  266|      0|            return;
  267|      0|        }
  268|  8.06k|        Clear();
  269|  8.06k|        BaseAllocator *a = shared_->ownBaseAllocator;
  270|  8.06k|        if (shared_->ownBuffer) {
  ------------------
  |  Branch (270:13): [True: 8.06k, False: 0]
  ------------------
  271|  8.06k|            baseAllocator_->Free(shared_);
  272|  8.06k|        }
  273|  8.06k|        RAPIDJSON_DELETE(a);
  ------------------
  |  |  716|  8.06k|#define RAPIDJSON_DELETE(x) delete x
  ------------------
  274|  8.06k|    }

_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE6IsBoolEv:
 1115|  18.1k|    bool IsBool()   const { return (data_.f.flags & kBoolFlag) != 0; }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE7GetBoolEv:
 1176|  9.08k|    bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }
  ------------------
  |  |  437|  9.08k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1176:28): [True: 9.08k, False: 0]
  ------------------
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE8IsNumberEv:
 1118|   353k|    bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE9GetDoubleEv:
 1825|   160k|    double GetDouble() const {
 1826|   160k|        RAPIDJSON_ASSERT(IsNumber());
  ------------------
  |  |  437|   160k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1826:9): [True: 160k, False: 0]
  ------------------
 1827|   160k|        if ((data_.f.flags & kDoubleFlag) != 0)                return data_.n.d;   // exact type, no conversion.
  ------------------
  |  Branch (1827:13): [True: 139k, False: 20.9k]
  ------------------
 1828|  20.9k|        if ((data_.f.flags & kIntFlag) != 0)                   return data_.n.i.i; // int -> double
  ------------------
  |  Branch (1828:13): [True: 20.9k, False: 55]
  ------------------
 1829|     55|        if ((data_.f.flags & kUintFlag) != 0)                  return data_.n.u.u; // unsigned -> double
  ------------------
  |  Branch (1829:13): [True: 4, 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: 46, False: 5]
  ------------------
 1831|      5|        RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0);  return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
  ------------------
  |  |  437|      5|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1831:9): [True: 5, False: 0]
  ------------------
 1832|      5|    }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE8IsStringEv:
 1124|  12.1M|    bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE9GetStringEv:
 1853|   736k|    const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return DataString(data_); }
  ------------------
  |  |  437|   736k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1853:35): [True: 736k, False: 0]
  ------------------
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE10DataStringERKNS6_4DataE:
 2107|   736k|    static RAPIDJSON_FORCEINLINE const Ch* DataString(const Data& data) {
 2108|   736k|        return (data.f.flags & kInlineStrFlag) ? data.ss.str : RAPIDJSON_GETPOINTER(Ch, data.s.str);
  ------------------
  |  |  347|   736k|#define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast<type *>(reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF))))
  |  |  ------------------
  |  |  |  |  320|   736k|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  |  |  ------------------
  ------------------
  |  Branch (2108:16): [True: 0, False: 736k]
  ------------------
 2109|   736k|    }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE15GetStringLengthEv:
 1858|  5.50M|    SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return DataStringLength(data_); }
  ------------------
  |  |  437|  5.50M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1858:40): [True: 5.50M, False: 0]
  ------------------
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE16DataStringLengthERKNS6_4DataE:
 2110|  5.50M|    static RAPIDJSON_FORCEINLINE SizeType DataStringLength(const Data& data) {
 2111|  5.50M|        return (data.f.flags & kInlineStrFlag) ? data.ss.GetLength() : data.s.length;
  ------------------
  |  Branch (2111:16): [True: 0, False: 5.50M]
  ------------------
 2112|  5.50M|    }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE8IsUint64Ev:
 1122|  35.9k|    bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE9GetUint64Ev:
 1820|  35.8k|    uint64_t GetUint64() const  { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }
  ------------------
  |  |  437|  35.8k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1820:35): [True: 35.8k, False: 0]
  ------------------
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE7IsInt64Ev:
 1121|     25|    bool IsInt64()  const { return (data_.f.flags & kInt64Flag) != 0; }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE8GetInt64Ev:
 1819|      7|    int64_t GetInt64() const    { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }
  ------------------
  |  |  437|      7|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1819:35): [True: 7, False: 0]
  ------------------
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE8IsObjectEv:
 1116|  4.48M|    bool IsObject() const { return data_.f.flags == kObjectFlag; }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE10FindMemberEPKc:
 1337|   347k|    MemberIterator FindMember(const Ch* name) {
 1338|   347k|        GenericValue n(StringRef(name));
 1339|   347k|        return FindMember(n);
 1340|   347k|    }
_ZN9rapidjson9StringRefIcEENS_16GenericStringRefIT_EEPKS2_:
  454|   347k|inline GenericStringRef<CharType> StringRef(const CharType* str) {
  455|   347k|    return GenericStringRef<CharType>(str);
  456|   347k|}
_ZN9rapidjson16GenericStringRefIcE13NotNullStrLenEPKc:
  423|   347k|    SizeType NotNullStrLen(const CharType* str) {
  424|   347k|        RAPIDJSON_ASSERT(str != 0);
  ------------------
  |  |  437|   347k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (424:9): [True: 347k, False: 0]
  ------------------
  425|   347k|        return internal::StrLen(str);
  426|   347k|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE12SetStringRawENS_16GenericStringRefIcEE:
 2435|  4.32M|    void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
 2436|  4.32M|        data_.f.flags = kConstStringFlag;
 2437|  4.32M|        SetStringPointer(s);
 2438|  4.32M|        data_.s.length = s.length;
 2439|  4.32M|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE16SetStringPointerEPKc:
 2115|  4.32M|    RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
  ------------------
  |  |  346|  4.32M|#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|  4.32M|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  |  |  ------------------
  ------------------
_ZNK9rapidjson16GenericStringRefIcEcvPKcEv:
  417|  4.32M|    operator const Ch *() const { return s; }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE18GetElementsPointerEv:
 2116|   373k|    RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
  ------------------
  |  |  347|   373k|#define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast<type *>(reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF))))
  |  |  ------------------
  |  |  |  |  320|   373k|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  |  |  ------------------
  ------------------
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE17GetMembersPointerEv:
 2118|  3.69M|    RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
  ------------------
  |  |  347|  3.69M|#define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast<type *>(reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF))))
  |  |  ------------------
  |  |  |  |  320|  3.69M|#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|   347k|    MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
 1359|   347k|        RAPIDJSON_ASSERT(IsObject());
  ------------------
  |  |  437|   347k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1359:9): [True: 347k, False: 0]
  ------------------
 1360|   347k|        RAPIDJSON_ASSERT(name.IsString());
  ------------------
  |  |  437|   347k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1360:9): [True: 347k, False: 0]
  ------------------
 1361|   347k|        return DoFindMember(name);
 1362|   347k|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE12DoFindMemberIS5_EEPNS_13GenericMemberIS2_S5_EERKNS0_IS2_T_EE:
 2282|   347k|    MemberIterator DoFindMember(const GenericValue<Encoding, SourceAllocator>& name) {
 2283|   347k|        MemberIterator member = MemberBegin();
 2284|  2.94M|        for ( ; member != MemberEnd(); ++member)
  ------------------
  |  Branch (2284:17): [True: 2.73M, False: 203k]
  ------------------
 2285|  2.73M|            if (name.StringEqual(member->name))
  ------------------
  |  Branch (2285:17): [True: 143k, False: 2.59M]
  ------------------
 2286|   143k|                break;
 2287|   347k|        return member;
 2288|   347k|    }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE11StringEqualIS5_EEbRKNS0_IS2_T_EE:
 2466|  2.73M|    bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {
 2467|  2.73M|        RAPIDJSON_ASSERT(IsString());
  ------------------
  |  |  437|  2.73M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (2467:9): [True: 2.73M, False: 0]
  ------------------
 2468|  2.73M|        RAPIDJSON_ASSERT(rhs.IsString());
  ------------------
  |  |  437|  2.73M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (2468:9): [True: 2.73M, False: 0]
  ------------------
 2469|       |
 2470|  2.73M|        const SizeType len1 = GetStringLength();
 2471|  2.73M|        const SizeType len2 = rhs.GetStringLength();
 2472|  2.73M|        if(len1 != len2) { return false; }
  ------------------
  |  Branch (2472:12): [True: 2.41M, False: 328k]
  ------------------
 2473|       |
 2474|   328k|        const Ch* const str1 = GetString();
 2475|   328k|        const Ch* const str2 = rhs.GetString();
 2476|   328k|        if(str1 == str2) { return true; } // fast path for constant string
  ------------------
  |  Branch (2476:12): [True: 0, False: 328k]
  ------------------
 2477|       |
 2478|   328k|        return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
 2479|   328k|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE9MemberEndEv:
 1277|  3.33M|    MemberIterator MemberEnd()              { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }
  ------------------
  |  |  437|  3.33M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1277:47): [True: 3.33M, False: 0]
  ------------------
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE6IsUintEv:
 1120|  49.2k|    bool IsUint()   const { return (data_.f.flags & kUintFlag) != 0; }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE7IsArrayEv:
 1117|   566k|    bool IsArray()  const { return data_.f.flags == kArrayFlag; }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE11MemberBeginEv:
 1274|   356k|    MemberIterator MemberBegin()            { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }
  ------------------
  |  |  437|   356k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1274:47): [True: 356k, False: 0]
  ------------------
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE4SizeEv:
 1643|  80.9k|    SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
  ------------------
  |  |  437|  80.9k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1643:29): [True: 80.9k, False: 0]
  ------------------
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEixEj:
 1668|   373k|    GenericValue& operator[](SizeType index) {
 1669|   373k|        RAPIDJSON_ASSERT(IsArray());
  ------------------
  |  |  437|   373k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1669:9): [True: 373k, False: 0]
  ------------------
 1670|   373k|        RAPIDJSON_ASSERT(index < data_.a.size);
  ------------------
  |  |  437|   373k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1670:9): [True: 373k, False: 0]
  ------------------
 1671|   373k|        return GetElementsPointer()[index];
 1672|   373k|    }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE8IsDoubleEv:
 1123|     18|    bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE11MemberCountEv:
 1191|  8.23k|    SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
  ------------------
  |  |  437|  8.23k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1191:36): [True: 8.23k, False: 0]
  ------------------
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE7GetUintEv:
 1818|  48.6k|    unsigned GetUint() const    { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag);  return data_.n.u.u;   }
  ------------------
  |  |  437|  48.6k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1818:35): [True: 48.6k, False: 0]
  ------------------
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE5IsIntEv:
 1119|  8.89k|    bool IsInt()    const { return (data_.f.flags & kIntFlag) != 0; }
_ZNK9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE6GetIntEv:
 1817|  8.87k|    int GetInt() const          { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag);   return data_.n.i.i;   }
  ------------------
  |  |  437|  8.87k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1817:35): [True: 8.87k, False: 0]
  ------------------
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE7SetNullEv:
 1169|  8.06k|    GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E7DestroyEv:
 2877|  8.06k|    void Destroy() {
 2878|  8.06k|        RAPIDJSON_DELETE(ownAllocator_);
  ------------------
  |  |  716|  8.06k|#define RAPIDJSON_DELETE(x) delete x
  ------------------
 2879|  8.06k|    }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E11ParseInsituEPc:
 2694|  8.06k|    GenericDocument& ParseInsitu(Ch* str) {
 2695|  8.06k|        return ParseInsitu<kParseDefaultFlags>(str);
 2696|  8.06k|    }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E11ParseInsituILj0EEERS6_Pc:
 2685|  8.06k|    GenericDocument& ParseInsitu(Ch* str) {
 2686|  8.06k|        GenericInsituStringStream<Encoding> s(str);
 2687|  8.06k|        return ParseStream<parseFlags | kParseInsituFlag>(s);
 2688|  8.06k|    }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E11ParseStreamILj1ENS_25GenericInsituStringStreamIS2_EEEERS6_RT0_:
 2661|  8.06k|    GenericDocument& ParseStream(InputStream& is) {
 2662|  8.06k|        return ParseStream<parseFlags, Encoding, InputStream>(is);
 2663|  8.06k|    }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E11ParseStreamILj1ES2_NS_25GenericInsituStringStreamIS2_EEEERS6_RT1_:
 2642|  8.06k|    GenericDocument& ParseStream(InputStream& is) {
 2643|  8.06k|        GenericReader<SourceEncoding, Encoding, StackAllocator> reader(
 2644|  8.06k|            stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
  ------------------
  |  Branch (2644:13): [True: 0, False: 8.06k]
  ------------------
 2645|  8.06k|        ClearStackOnExit scope(*this);
 2646|  8.06k|        parseResult_ = reader.template Parse<parseFlags>(is, *this);
 2647|  8.06k|        if (parseResult_) {
  ------------------
  |  Branch (2647:13): [True: 5.33k, False: 2.73k]
  ------------------
 2648|  5.33k|            RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
  ------------------
  |  |  437|  5.33k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (2648:13): [True: 5.33k, False: 0]
  ------------------
 2649|  5.33k|            ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
 2650|  5.33k|        }
 2651|  8.06k|        return *this;
 2652|  8.06k|    }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E10ClearStackEv:
 2868|  8.06k|    void ClearStack() {
 2869|  8.06k|        if (Allocator::kNeedFree)
  ------------------
  |  Branch (2869:13): [Folded, False: 8.06k]
  ------------------
 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.06k|        else
 2873|  8.06k|            stack_.Clear();
 2874|  8.06k|        stack_.ShrinkToFit();
 2875|  8.06k|    }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E11StartObjectEv:
 2844|  3.75M|    bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E10StartArrayEv:
 2854|  4.86M|    bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E3KeyEPKcjb:
 2846|  3.86M|    bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E6StringEPKcjb:
 2836|  3.97M|    bool String(const Ch* str, SizeType length, bool copy) { 
 2837|  3.97M|        if (copy) 
  ------------------
  |  Branch (2837:13): [True: 0, False: 3.97M]
  ------------------
 2838|      0|            new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
 2839|  3.97M|        else
 2840|  3.97M|            new (stack_.template Push<ValueType>()) ValueType(str, length);
 2841|  3.97M|        return true;
 2842|  3.97M|    }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E12GetAllocatorEv:
 2795|  3.98M|    Allocator& GetAllocator() {
 2796|  3.98M|        RAPIDJSON_ASSERT(allocator_);
  ------------------
  |  |  437|  3.98M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (2796:9): [True: 3.98M, False: 0]
  ------------------
 2797|  3.98M|        return *allocator_;
 2798|  3.98M|    }
_ZN9rapidjson9StringRefIcEENS_16GenericStringRefIT_EEPKS2_m:
  474|  3.97M|inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
  475|  3.97M|    return GenericStringRef<CharType>(str, SizeType(length));
  476|  3.97M|}
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E9EndObjectEj:
 2848|  3.75M|    bool EndObject(SizeType memberCount) {
 2849|  3.75M|        typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
 2850|  3.75M|        stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
 2851|  3.75M|        return true;
 2852|  3.75M|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE12SetObjectRawEPNS_13GenericMemberIS2_S5_EEjRS5_:
 2415|  3.75M|    void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
 2416|  3.75M|        data_.f.flags = kObjectFlag;
 2417|  3.75M|        if (count) {
  ------------------
  |  Branch (2417:13): [True: 913k, False: 2.84M]
  ------------------
 2418|   913k|            Member* m = DoAllocMembers(count, allocator);
 2419|   913k|            SetMembersPointer(m);
 2420|   913k|            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|   913k|        }
 2429|  2.84M|        else
 2430|  2.84M|            SetMembersPointer(0);
 2431|  3.75M|        data_.o.size = data_.o.capacity = count;
 2432|  3.75M|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE14DoAllocMembersEjRS5_:
 2268|   913k|    RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) {
 2269|   913k|        return Malloc<Member>(allocator, capacity);
 2270|   913k|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE17SetMembersPointerEPNS_13GenericMemberIS2_S5_EE:
 2119|  3.75M|    RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
  ------------------
  |  |  346|  3.75M|#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.75M|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  |  |  ------------------
  ------------------
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E8EndArrayEj:
 2856|   227k|    bool EndArray(SizeType elementCount) {
 2857|   227k|        ValueType* elements = stack_.template Pop<ValueType>(elementCount);
 2858|   227k|        stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
 2859|   227k|        return true;
 2860|   227k|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE11SetArrayRawEPS6_jRS5_:
 2402|   227k|    void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
 2403|   227k|        data_.f.flags = kArrayFlag;
 2404|   227k|        if (count) {
  ------------------
  |  Branch (2404:13): [True: 223k, False: 4.25k]
  ------------------
 2405|   223k|            GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
 2406|   223k|            SetElementsPointer(e);
 2407|   223k|            std::memcpy(static_cast<void*>(e), values, count * sizeof(GenericValue));
 2408|   223k|        }
 2409|  4.25k|        else
 2410|  4.25k|            SetElementsPointer(0);
 2411|   227k|        data_.a.size = data_.a.capacity = count;
 2412|   227k|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE18SetElementsPointerEPS6_:
 2117|   227k|    RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
  ------------------
  |  |  346|   227k|#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|   227k|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  |  |  ------------------
  ------------------
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E4NullEv:
 2820|  3.31k|    bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E4BoolEb:
 2821|  61.6k|    bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E6DoubleEd:
 2826|   506k|    bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E5Int64El:
 2824|  26.7k|    bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E6Uint64Em:
 2825|  16.6k|    bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E3IntEi:
 2822|  78.4k|    bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E4UintEj:
 2823|  25.9M|    bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEaSERS6_:
  921|  5.33k|    GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
  922|  5.33k|        if (RAPIDJSON_LIKELY(this != &rhs)) {
  ------------------
  |  |  492|  5.33k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 5.33k, 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.33k|            GenericValue temp;
  927|  5.33k|            temp.RawAssign(rhs);
  928|  5.33k|            this->~GenericValue();
  929|  5.33k|            RawAssign(temp);
  930|  5.33k|        }
  931|  5.33k|        return *this;
  932|  5.33k|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEE9RawAssignERS6_:
 2459|  10.6k|    void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
 2460|  10.6k|        data_ = rhs.data_;
 2461|       |        // data_.f.flags = rhs.data_.f.flags;
 2462|  10.6k|        rhs.data_.f.flags = kNullFlag;
 2463|  10.6k|    }
_ZNK9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E13HasParseErrorEv:
 2771|  8.06k|    bool HasParseError() const { return parseResult_.IsError(); }
_ZNK9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E14GetErrorOffsetEv:
 2777|  2.73k|    size_t GetErrorOffset() const { return parseResult_.Offset(); }
_ZNK9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E13GetParseErrorEv:
 2774|  2.73k|    ParseErrorCode GetParseError() const { return parseResult_.Code(); }
_ZN9rapidjson16GenericStringRefIcEC2EPKc:
  400|   347k|        : s(str), length(NotNullStrLen(str)) {}
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2ENS_16GenericStringRefIcEE:
  840|   347k|    explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }
_ZN9rapidjson16GenericStringRefIcEC2ERKS1_:
  414|   347k|    GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEED2Ev:
  880|   373k|    ~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|   373k|        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|   373k|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2Ev:
  690|  24.7k|    GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2ENS_4TypeE:
  720|  8.62M|    explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {
  721|  8.62M|        static const uint16_t defaultFlags[] = {
  722|  8.62M|            kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
  723|  8.62M|            kNumberAnyFlag
  724|  8.62M|        };
  725|  8.62M|        RAPIDJSON_NOEXCEPT_ASSERT(type >= kNullType && type <= kNumberType);
  ------------------
  |  |  687|  8.62M|#define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x)
  |  |  ------------------
  |  |  |  |  437|  8.62M|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  ------------------
  ------------------
  |  Branch (725:9): [True: 8.62M, False: 0]
  |  Branch (725:9): [True: 8.62M, False: 0]
  |  Branch (725:9): [True: 8.62M, False: 0]
  ------------------
  726|  8.62M|        data_.f.flags = defaultFlags[type];
  727|       |
  728|       |        // Use ShortString to store empty string.
  729|  8.62M|        if (type == kStringType)
  ------------------
  |  Branch (729:13): [True: 0, False: 8.62M]
  ------------------
  730|      0|            data_.ss.SetLength(0);
  731|  8.62M|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2Ej:
  798|  25.9M|    explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {
  799|  25.9M|        data_.n.u64 = u; 
  800|  25.9M|        data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
  ------------------
  |  Branch (800:25): [True: 2.53k, False: 25.9M]
  ------------------
  801|  25.9M|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2Ei:
  792|  78.4k|    explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() {
  793|  78.4k|        data_.n.i64 = i;
  794|  78.4k|        data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
  ------------------
  |  Branch (794:25): [True: 1.18k, False: 77.2k]
  ------------------
  795|  78.4k|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2Ed:
  831|   506k|    explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2El:
  804|  26.7k|    explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() {
  805|  26.7k|        data_.n.i64 = i64;
  806|  26.7k|        data_.f.flags = kNumberInt64Flag;
  807|  26.7k|        if (i64 >= 0) {
  ------------------
  |  Branch (807:13): [True: 0, False: 26.7k]
  ------------------
  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|  26.7k|        else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
  ------------------
  |  |  320|  26.7k|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  ------------------
  |  Branch (814:18): [True: 0, False: 26.7k]
  ------------------
  815|      0|            data_.f.flags |= kIntFlag;
  816|  26.7k|    }
_ZN9rapidjson16GenericStringRefIcEC2EPKcj:
  412|  3.97M|        : s(RAPIDJSON_LIKELY(str) ? str : emptyString), length(len) { RAPIDJSON_ASSERT(str != 0 || len == 0u); }
  ------------------
  |  |  492|  3.97M|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 3.97M, False: 0]
  |  |  ------------------
  ------------------
                      : s(RAPIDJSON_LIKELY(str) ? str : emptyString), length(len) { RAPIDJSON_ASSERT(str != 0 || len == 0u); }
  ------------------
  |  |  437|  3.97M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (412:71): [True: 3.97M, False: 0]
  |  Branch (412:71): [True: 0, False: 0]
  |  Branch (412:71): [True: 3.97M, False: 0]
  ------------------
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2Em:
  819|  16.6k|    explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() {
  820|  16.6k|        data_.n.u64 = u64;
  821|  16.6k|        data_.f.flags = kNumberUint64Flag;
  822|  16.6k|        if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
  ------------------
  |  |  320|  16.6k|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  ------------------
  |  Branch (822:13): [True: 13.3k, False: 3.32k]
  ------------------
  823|  13.3k|            data_.f.flags |= kInt64Flag;
  824|  16.6k|        if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
  ------------------
  |  |  320|  16.6k|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  ------------------
  |  Branch (824:13): [True: 0, False: 16.6k]
  ------------------
  825|      0|            data_.f.flags |= kUintFlag;
  826|  16.6k|        if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
  ------------------
  |  |  320|  16.6k|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  ------------------
  |  Branch (826:13): [True: 0, False: 16.6k]
  ------------------
  827|      0|            data_.f.flags |= kIntFlag;
  828|  16.6k|    }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_EC2EPS5_mPS4_:
 2527|  8.06k|        allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
 2528|  8.06k|    {
 2529|  8.06k|        if (!allocator_)
  ------------------
  |  Branch (2529:13): [True: 8.06k, False: 0]
  ------------------
 2530|  8.06k|            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
  ------------------
  |  |  712|  8.06k|#define RAPIDJSON_NEW(TypeName) new TypeName
  ------------------
 2531|  8.06k|    }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E16ClearStackOnExitC2ERS6_:
 2806|  8.06k|        explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2IbEET_PNS_8internal8EnableIfINS9_15RemoveSfinaeTagIPFRNS9_9SfinaeTagENS9_6IsSameIbS8_EEEE4TypeEvE4TypeE:
  785|  61.6k|        : data_() {
  786|       |            // safe-guard against failing SFINAE
  787|  61.6k|            RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value));
  ------------------
  |  |  447|  61.6k|   static_assert(x, RAPIDJSON_STRINGIFY(x))
  ------------------
  788|  61.6k|            data_.f.flags = b ? kTrueFlag : kFalseFlag;
  ------------------
  |  Branch (788:29): [True: 38.0k, False: 23.6k]
  ------------------
  789|  61.6k|    }
_ZN9rapidjson12GenericValueINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEEEC2EPKcj:
  837|  3.97M|    GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_E16ClearStackOnExitD2Ev:
 2807|  8.06k|        ~ClearStackOnExit() { d_.ClearStack(); }
_ZN9rapidjson15GenericDocumentINS_4UTF8IcEENS_19MemoryPoolAllocatorINS_12CrtAllocatorEEES4_ED2Ev:
 2548|  8.06k|    ~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.06k|        if (ownAllocator_) {
  ------------------
  |  Branch (2553:13): [True: 8.06k, False: 0]
  ------------------
 2554|  8.06k|            ValueType::SetNull();
 2555|  8.06k|        }
 2556|  8.06k|        Destroy();
 2557|  8.06k|    }

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

_ZN9rapidjson16GetParseError_EnENS_14ParseErrorCodeE:
   36|  2.73k|inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) {
   37|  2.73k|    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.73k]
  ------------------
   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.70k]
  ------------------
   41|    270|        case kParseErrorDocumentRootNotSingular:        return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values.");
  ------------------
  |  |   52|    270|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (41:9): [True: 270, False: 2.46k]
  ------------------
   42|       |
   43|    964|        case kParseErrorValueInvalid:                   return RAPIDJSON_ERROR_STRING("Invalid value.");
  ------------------
  |  |   52|    964|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (43:9): [True: 964, False: 1.76k]
  ------------------
   44|       |
   45|    180|        case kParseErrorObjectMissName:                 return RAPIDJSON_ERROR_STRING("Missing a name for object member.");
  ------------------
  |  |   52|    180|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (45:9): [True: 180, False: 2.55k]
  ------------------
   46|     74|        case kParseErrorObjectMissColon:                return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member.");
  ------------------
  |  |   52|     74|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (46:9): [True: 74, False: 2.65k]
  ------------------
   47|     70|        case kParseErrorObjectMissCommaOrCurlyBracket:  return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member.");
  ------------------
  |  |   52|     70|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (47:9): [True: 70, False: 2.66k]
  ------------------
   48|       |
   49|    878|        case kParseErrorArrayMissCommaOrSquareBracket:  return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element.");
  ------------------
  |  |   52|    878|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (49:9): [True: 878, False: 1.85k]
  ------------------
   50|       |
   51|     58|        case kParseErrorStringUnicodeEscapeInvalidHex:  return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string.");
  ------------------
  |  |   52|     58|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (51:9): [True: 58, False: 2.67k]
  ------------------
   52|     36|        case kParseErrorStringUnicodeSurrogateInvalid:  return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid.");
  ------------------
  |  |   52|     36|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (52:9): [True: 36, False: 2.69k]
  ------------------
   53|      8|        case kParseErrorStringEscapeInvalid:            return RAPIDJSON_ERROR_STRING("Invalid escape character in string.");
  ------------------
  |  |   52|      8|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (53:9): [True: 8, False: 2.72k]
  ------------------
   54|     84|        case kParseErrorStringMissQuotationMark:        return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string.");
  ------------------
  |  |   52|     84|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (54:9): [True: 84, False: 2.64k]
  ------------------
   55|     26|        case kParseErrorStringInvalidEncoding:          return RAPIDJSON_ERROR_STRING("Invalid encoding in string.");
  ------------------
  |  |   52|     26|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (55:9): [True: 26, False: 2.70k]
  ------------------
   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.72k]
  ------------------
   58|      6|        case kParseErrorNumberMissFraction:             return RAPIDJSON_ERROR_STRING("Miss fraction part in number.");
  ------------------
  |  |   52|      6|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (58:9): [True: 6, False: 2.72k]
  ------------------
   59|     48|        case kParseErrorNumberMissExponent:             return RAPIDJSON_ERROR_STRING("Miss exponent in number.");
  ------------------
  |  |   52|     48|#define RAPIDJSON_ERROR_STRING(x) x
  ------------------
  |  Branch (59:9): [True: 48, False: 2.68k]
  ------------------
   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.73k]
  ------------------
   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.73k]
  ------------------
   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.73k]
  ------------------
   65|  2.73k|    }
   66|  2.73k|}

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

_ZN9rapidjson8internal5Pow10Ei:
   28|   506k|inline double Pow10(int n) {
   29|   506k|    static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes
   30|   506k|        1e+0,  
   31|   506k|        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|   506k|        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|   506k|        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|   506k|        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|   506k|        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|   506k|        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|   506k|        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|   506k|        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|   506k|        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|   506k|        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|   506k|        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|   506k|        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|   506k|        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|   506k|        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|   506k|        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|   506k|        1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308
   47|   506k|    };
   48|   506k|    RAPIDJSON_ASSERT(n >= 0 && n <= 308);
  ------------------
  |  |  437|   506k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (48:5): [True: 506k, False: 0]
  |  Branch (48:5): [True: 506k, False: 0]
  |  Branch (48:5): [True: 506k, False: 0]
  ------------------
   49|   506k|    return e[n];
   50|   506k|}

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

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

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

_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE5ParseILj1ENS_25GenericInsituStringStreamIS2_EENS_15GenericDocumentIS2_NS_19MemoryPoolAllocatorIS3_EES3_EEEENS_11ParseResultERT0_RT1_:
  559|  8.06k|    ParseResult Parse(InputStream& is, Handler& handler) {
  560|  8.06k|        if (parseFlags & kParseIterativeFlag)
  ------------------
  |  Branch (560:13): [Folded, False: 8.06k]
  ------------------
  561|      0|            return IterativeParse<parseFlags>(is, handler);
  562|       |
  563|  8.06k|        parseResult_.Clear();
  564|       |
  565|  8.06k|        ClearStackOnExit scope(*this);
  566|       |
  567|  8.06k|        SkipWhitespaceAndComments<parseFlags>(is);
  568|  8.06k|        RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
  ------------------
  |  |   61|  8.06k|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|  8.06k|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |   62|  8.06k|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  ------------------
  |  |  |  |  505|  8.06k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (505:31): [True: 0, False: 8.06k]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   63|  8.06k|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|  8.06k|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|  8.06k|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 8.06k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  569|       |
  570|  8.06k|        if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) {
  ------------------
  |  |  505|  8.06k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 24, False: 8.04k]
  |  |  ------------------
  ------------------
  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.04k|        else {
  575|  8.04k|            ParseValue<parseFlags>(is, handler);
  576|  8.04k|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
  ------------------
  |  |   61|  8.04k|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|  8.04k|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |   62|  8.04k|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  ------------------
  |  |  |  |  505|  8.04k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (505:31): [True: 2.43k, False: 5.60k]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   63|  8.04k|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|  8.04k|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|  8.04k|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 5.60k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  577|       |
  578|  5.60k|            if (!(parseFlags & kParseStopWhenDoneFlag)) {
  ------------------
  |  Branch (578:17): [True: 5.60k, Folded]
  ------------------
  579|  5.60k|                SkipWhitespaceAndComments<parseFlags>(is);
  580|  5.60k|                RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
  ------------------
  |  |   61|  5.60k|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|  5.60k|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |   62|  5.60k|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  ------------------
  |  |  |  |  505|  5.60k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (505:31): [True: 0, False: 5.60k]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   63|  5.60k|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|  5.60k|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|  5.60k|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 5.60k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  581|       |
  582|  5.60k|                if (RAPIDJSON_UNLIKELY(is.Peek() != '\0')) {
  ------------------
  |  |  505|  5.60k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 270, False: 5.33k]
  |  |  ------------------
  ------------------
  583|    270|                    RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell());
  ------------------
  |  |  101|    270|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|    270|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  102|    270|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  ------------------
  |  |  |  |  437|    270|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  ------------------
  |  |  103|    270|    SetParseError(parseErrorCode, offset); \
  |  |  104|    270|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|    270|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|    270|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 270]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (583:21): [True: 270, False: 0]
  ------------------
  584|    270|                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
  ------------------
  |  |   61|    540|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|    270|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |   62|    540|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  ------------------
  |  |  |  |  505|    270|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (505:31): [True: 270, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   63|    540|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|    270|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|    270|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  585|    270|                }
  586|  5.60k|            }
  587|  5.60k|        }
  588|       |
  589|  5.33k|        return parseResult_;
  590|  8.06k|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE11ParseStringILj1ENS_25GenericInsituStringStreamIS2_EENS_15GenericDocumentIS2_NS_19MemoryPoolAllocatorIS3_EES3_EEEEvRT0_RT1_b:
  959|  3.97M|    void ParseString(InputStream& is, Handler& handler, bool isKey = false) {
  960|  3.97M|        internal::StreamLocalCopy<InputStream> copy(is);
  961|  3.97M|        InputStream& s(copy.s);
  962|       |
  963|  3.97M|        RAPIDJSON_ASSERT(s.Peek() == '\"');
  ------------------
  |  |  437|  3.97M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (963:9): [True: 3.97M, False: 0]
  ------------------
  964|  3.97M|        s.Take();  // Skip '\"'
  965|       |
  966|  3.97M|        bool success = false;
  967|  3.97M|        if (parseFlags & kParseInsituFlag) {
  ------------------
  |  Branch (967:13): [True: 3.97M, Folded]
  ------------------
  968|  3.97M|            typename InputStream::Ch *head = s.PutBegin();
  969|  3.97M|            ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);
  970|  3.97M|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  3.97M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  3.97M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  3.97M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  3.97M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  3.97M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 212, False: 3.97M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  3.97M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  3.97M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  3.97M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 3.97M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  971|  3.97M|            size_t length = s.PutEnd(head) - 1;
  972|  3.97M|            RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
  ------------------
  |  |  437|  3.97M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (972:13): [True: 3.97M, False: 0]
  ------------------
  973|  3.97M|            const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
  974|  3.97M|            success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false));
  ------------------
  |  Branch (974:24): [True: 3.86M, False: 109k]
  ------------------
  975|  3.97M|        }
  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|  3.97M|        if (RAPIDJSON_UNLIKELY(!success))
  ------------------
  |  |  505|  3.97M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 3.97M]
  |  |  ------------------
  ------------------
  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|  3.97M|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE19ParseStringToStreamILj1ES2_S2_NS_25GenericInsituStringStreamIS2_EES7_EEvRT2_RT3_:
  991|  3.97M|    RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) {
  992|       |//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
  993|  3.97M|#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  994|  3.97M|        static const char escape[256] = {
  995|  3.97M|            Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '/',
  ------------------
  |  |  993|  3.97M|#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|  3.97M|#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  ------------------
  996|  3.97M|            Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
  ------------------
  |  |  993|  3.97M|#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|  3.97M|#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  ------------------
  997|  3.97M|            0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
  998|  3.97M|            0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  999|  3.97M|            Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
  ------------------
  |  |  993|  3.97M|#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|  3.97M|#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|  3.97M|#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|  3.97M|#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|  3.97M|#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|  3.97M|#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|  3.97M|#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|  3.97M|#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  ------------------
 1000|  3.97M|        };
 1001|  3.97M|#undef Z16
 1002|       |//!@endcond
 1003|       |
 1004|  42.7M|        for (;;) {
 1005|       |            // Scan and copy string before "\\\"" or < 0x20. This is an optional optimzation.
 1006|  42.7M|            if (!(parseFlags & kParseValidateEncodingFlag))
  ------------------
  |  Branch (1006:17): [True: 42.7M, Folded]
  ------------------
 1007|  42.7M|                ScanCopyUnescapedString(is, os);
 1008|       |
 1009|  42.7M|            Ch c = is.Peek();
 1010|  42.7M|            if (RAPIDJSON_UNLIKELY(c == '\\')) {    // Escape
  ------------------
  |  |  505|  42.7M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 1.79k, False: 42.7M]
  |  |  ------------------
  ------------------
 1011|  1.79k|                size_t escapeOffset = is.Tell();    // For invalid escaping, report the initial '\\' as error offset
 1012|  1.79k|                is.Take();
 1013|  1.79k|                Ch e = is.Peek();
 1014|  1.79k|                if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) {
  ------------------
  |  |  492|  1.79k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 632, False: 1.16k]
  |  |  ------------------
  ------------------
  |  Branch (1014:22): [True: 1.79k, Folded]
  |  Branch (1014:41): [True: 0, False: 0]
  ------------------
 1015|    632|                    is.Take();
 1016|    632|                    os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
 1017|    632|                }
 1018|  1.16k|                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: 1.16k]
  ------------------
 1019|      0|                    is.Take();
 1020|      0|                    os.Put('\'');
 1021|      0|                }
 1022|  1.16k|                else if (RAPIDJSON_LIKELY(e == 'u')) {    // Unicode
  ------------------
  |  |  492|  1.16k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 1.15k, False: 8]
  |  |  ------------------
  ------------------
 1023|  1.15k|                    is.Take();
 1024|  1.15k|                    unsigned codepoint = ParseHex4(is, escapeOffset);
 1025|  1.15k|                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  1.15k|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  1.15k|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  1.15k|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  1.15k|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  1.15k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 40, False: 1.11k]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  1.15k|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  1.15k|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  1.15k|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 1.11k]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1026|  1.11k|                    if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDFFF)) {
  ------------------
  |  |  505|  1.87k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 531, False: 588]
  |  |  |  Branch (505:51): [True: 756, False: 363]
  |  |  |  Branch (505:51): [True: 531, False: 225]
  |  |  ------------------
  ------------------
 1027|       |                        // high surrogate, check if followed by valid low surrogate
 1028|    531|                        if (RAPIDJSON_LIKELY(codepoint <= 0xDBFF)) {
  ------------------
  |  |  492|    531|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 525, False: 6]
  |  |  ------------------
  ------------------
 1029|       |                            // Handle UTF-16 surrogate pair
 1030|    525|                            if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u')))
  ------------------
  |  |  505|  1.04k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 24, False: 501]
  |  |  |  Branch (505:51): [True: 2, False: 523]
  |  |  |  Branch (505:51): [True: 22, False: 501]
  |  |  ------------------
  ------------------
 1031|    525|                                RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
  ------------------
  |  |  120|     48|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     24|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|     48|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  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]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|     48|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|     24|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   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]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|     24|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     24|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     24|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1031:33): [True: 24, False: 0]
  ------------------
 1032|    501|                            unsigned codepoint2 = ParseHex4(is, escapeOffset);
 1033|    501|                            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|    501|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|    501|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|    501|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|    501|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|    501|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 18, False: 483]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|    501|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|    501|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|    501|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 483]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1034|    483|                            if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF))
  ------------------
  |  |  505|    960|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 6, False: 477]
  |  |  |  Branch (505:51): [True: 6, False: 477]
  |  |  |  Branch (505:51): [True: 0, False: 477]
  |  |  ------------------
  ------------------
 1035|    483|                                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|    477|                            codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
 1037|    477|                        }
 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|    531|                    }
 1044|  1.06k|                    TEncoding::Encode(os, codepoint);
 1045|  1.06k|                }
 1046|      8|                else
 1047|  1.16k|                    RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, escapeOffset);
  ------------------
  |  |  120|     16|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|      8|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|     16|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|      8|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|      8|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|      8|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|      8|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|      8|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|      8|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|      8|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|      8|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 8]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|     16|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|      8|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|     16|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|      8|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|     16|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|      8|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 8, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|     16|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|      8|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|      8|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|      8|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|      8|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|      8|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1047:21): [True: 8, False: 0]
  ------------------
 1048|  1.79k|            }
 1049|  42.7M|            else if (RAPIDJSON_UNLIKELY(c == '"')) {    // Closing double quote
  ------------------
  |  |  505|  42.7M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 3.97M, False: 38.7M]
  |  |  ------------------
  ------------------
 1050|  3.97M|                is.Take();
 1051|  3.97M|                os.Put('\0');   // null-terminate the string
 1052|  3.97M|                return;
 1053|  3.97M|            }
 1054|  38.7M|            else if (RAPIDJSON_UNLIKELY(static_cast<unsigned>(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
  ------------------
  |  |  505|  38.7M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 110, False: 38.7M]
  |  |  ------------------
  ------------------
 1055|    110|                if (c == '\0')
  ------------------
  |  Branch (1055:21): [True: 84, False: 26]
  ------------------
 1056|    110|                    RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell());
  ------------------
  |  |  120|    168|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     84|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|    168|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|     84|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|     84|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|     84|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|     84|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|     84|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|     84|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|     84|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|     84|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 84]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|    168|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|     84|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|    168|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|     84|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|    168|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|     84|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 84, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|    168|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|     84|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|     84|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|     84|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     84|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     84|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1056:21): [True: 84, False: 0]
  ------------------
 1057|     26|                else
 1058|    110|                    RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, is.Tell());
  ------------------
  |  |  120|     52|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     26|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|     52|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|     26|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|     26|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|     26|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|     26|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|     26|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|     26|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|     26|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|     26|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 26]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|     52|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|     26|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|     52|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|     26|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|     52|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|     26|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 26, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|     52|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|     26|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|     26|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|     26|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     26|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     26|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1058:21): [True: 26, False: 0]
  ------------------
 1059|    110|            }
 1060|  38.7M|            else {
 1061|  38.7M|                size_t offset = is.Tell();
 1062|  38.7M|                if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ?
  ------------------
  |  |  505|  77.4M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 38.7M]
  |  |  |  Branch (505:51): [Folded, False: 38.7M]
  |  |  ------------------
  ------------------
 1063|  38.7M|                    !Transcoder<SEncoding, TEncoding>::Validate(is, os) :
 1064|  38.7M|                    !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|  38.7M|            }
 1067|  42.7M|        }
 1068|  3.97M|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE23ScanCopyUnescapedStringINS_25GenericInsituStringStreamIS2_EES7_EEvRT_RT0_:
 1071|  42.7M|    static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) {
 1072|       |            // Do nothing for generic version
 1073|  42.7M|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE9ParseHex4INS_25GenericInsituStringStreamIS2_EEEEjRT_m:
  906|  1.66k|    unsigned ParseHex4(InputStream& is, size_t escapeOffset) {
  907|  1.66k|        unsigned codepoint = 0;
  908|  8.15k|        for (int i = 0; i < 4; i++) {
  ------------------
  |  Branch (908:25): [True: 6.55k, False: 1.60k]
  ------------------
  909|  6.55k|            Ch c = is.Peek();
  910|  6.55k|            codepoint <<= 4;
  911|  6.55k|            codepoint += static_cast<unsigned>(c);
  912|  6.55k|            if (c >= '0' && c <= '9')
  ------------------
  |  Branch (912:17): [True: 6.51k, False: 34]
  |  Branch (912:29): [True: 1.28k, False: 5.23k]
  ------------------
  913|  1.28k|                codepoint -= '0';
  914|  5.27k|            else if (c >= 'A' && c <= 'F')
  ------------------
  |  Branch (914:22): [True: 5.23k, False: 34]
  |  Branch (914:34): [True: 1.92k, False: 3.31k]
  ------------------
  915|  1.92k|                codepoint -= 'A' - 10;
  916|  3.35k|            else if (c >= 'a' && c <= 'f')
  ------------------
  |  Branch (916:22): [True: 3.30k, False: 46]
  |  Branch (916:34): [True: 3.29k, False: 12]
  ------------------
  917|  3.29k|                codepoint -= 'a' - 10;
  918|     58|            else {
  919|     58|                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, escapeOffset);
  ------------------
  |  |  101|     58|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     58|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  102|     58|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  ------------------
  |  |  |  |  437|     58|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  ------------------
  |  |  103|     58|    SetParseError(parseErrorCode, offset); \
  |  |  104|     58|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     58|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     58|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 58]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (919:17): [True: 58, False: 0]
  ------------------
  920|     58|                RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0);
  ------------------
  |  |   61|    116|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     58|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |   62|    116|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  ------------------
  |  |  |  |  505|     58|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (505:31): [True: 58, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   63|    116|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     58|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     58|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  921|     58|            }
  922|  6.49k|            is.Take();
  923|  6.49k|        }
  924|  1.60k|        return codepoint;
  925|  1.66k|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE7ConsumeINS_25GenericInsituStringStreamIS2_EEEEbRT_NS8_2ChE:
  895|  39.8M|    RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) {
  896|  39.8M|        if (RAPIDJSON_LIKELY(is.Peek() == expect)) {
  ------------------
  |  |  492|  39.8M|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 33.8M, False: 6.00M]
  |  |  ------------------
  ------------------
  897|  33.8M|            is.Take();
  898|  33.8M|            return true;
  899|  33.8M|        }
  900|  6.00M|        else
  901|  6.00M|            return false;
  902|  39.8M|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE10ClearStackEv:
  698|  8.06k|    void ClearStack() { stack_.Clear(); }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE25SkipWhitespaceAndCommentsILj1ENS_25GenericInsituStringStreamIS2_EEEEvRT0_:
  711|  76.7M|    void SkipWhitespaceAndComments(InputStream& is) {
  712|  76.7M|        SkipWhitespace(is);
  713|       |
  714|  76.7M|        if (parseFlags & kParseCommentsFlag) {
  ------------------
  |  Branch (714:13): [Folded, False: 76.7M]
  ------------------
  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|  76.7M|    }
_ZN9rapidjson14SkipWhitespaceINS_25GenericInsituStringStreamINS_4UTF8IcEEEEEEvRT_:
  266|  76.7M|void SkipWhitespace(InputStream& is) {
  267|  76.7M|    internal::StreamLocalCopy<InputStream> copy(is);
  268|  76.7M|    InputStream& s(copy.s);
  269|       |
  270|  76.7M|    typename InputStream::Ch c;
  271|  76.9M|    while ((c = s.Peek()) == ' ' || c == '\n' || c == '\r' || c == '\t')
  ------------------
  |  Branch (271:12): [True: 152k, False: 76.7M]
  |  Branch (271:37): [True: 14.0k, False: 76.7M]
  |  Branch (271:50): [True: 5.74k, False: 76.7M]
  |  Branch (271:63): [True: 3.35k, False: 76.7M]
  ------------------
  272|   175k|        s.Take();
  273|  76.7M|}
_ZNK9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE13HasParseErrorEv:
  682|   119M|    bool HasParseError() const { return parseResult_.IsError(); }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE13SetParseErrorENS_14ParseErrorCodeEm:
  691|  2.73k|    void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE10ParseValueILj1ENS_25GenericInsituStringStreamIS2_EENS_15GenericDocumentIS2_NS_19MemoryPoolAllocatorIS3_EES3_EEEEvRT0_RT1_:
 1752|  35.4M|    void ParseValue(InputStream& is, Handler& handler) {
 1753|  35.4M|        switch (is.Peek()) {
 1754|  3.34k|            case 'n': ParseNull  <parseFlags>(is, handler); break;
  ------------------
  |  Branch (1754:13): [True: 3.34k, False: 35.4M]
  ------------------
 1755|  38.1k|            case 't': ParseTrue  <parseFlags>(is, handler); break;
  ------------------
  |  Branch (1755:13): [True: 38.1k, False: 35.3M]
  ------------------
 1756|  23.6k|            case 'f': ParseFalse <parseFlags>(is, handler); break;
  ------------------
  |  Branch (1756:13): [True: 23.6k, False: 35.3M]
  ------------------
 1757|   109k|            case '"': ParseString<parseFlags>(is, handler); break;
  ------------------
  |  Branch (1757:13): [True: 109k, False: 35.2M]
  ------------------
 1758|  3.75M|            case '{': ParseObject<parseFlags>(is, handler); break;
  ------------------
  |  Branch (1758:13): [True: 3.75M, False: 31.6M]
  ------------------
 1759|  4.86M|            case '[': ParseArray <parseFlags>(is, handler); break;
  ------------------
  |  Branch (1759:13): [True: 4.86M, False: 30.5M]
  ------------------
 1760|  26.6M|            default :
  ------------------
  |  Branch (1760:13): [True: 26.6M, False: 8.80M]
  ------------------
 1761|  26.6M|                      ParseNumber<parseFlags>(is, handler);
 1762|  26.6M|                      break;
 1763|       |
 1764|  35.4M|        }
 1765|  35.4M|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE9ParseNullILj1ENS_25GenericInsituStringStreamIS2_EENS_15GenericDocumentIS2_NS_19MemoryPoolAllocatorIS3_EES3_EEEEvRT0_RT1_:
  856|  3.34k|    void ParseNull(InputStream& is, Handler& handler) {
  857|  3.34k|        RAPIDJSON_ASSERT(is.Peek() == 'n');
  ------------------
  |  |  437|  3.34k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (857:9): [True: 3.34k, False: 0]
  ------------------
  858|  3.34k|        is.Take();
  859|       |
  860|  3.34k|        if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) {
  ------------------
  |  |  492|  13.3k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 3.31k, False: 30]
  |  |  |  Branch (492:49): [True: 3.32k, False: 22]
  |  |  |  Branch (492:49): [True: 3.31k, False: 6]
  |  |  |  Branch (492:49): [True: 3.31k, False: 2]
  |  |  ------------------
  ------------------
  861|  3.31k|            if (RAPIDJSON_UNLIKELY(!handler.Null()))
  ------------------
  |  |  505|  3.31k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 3.31k]
  |  |  ------------------
  ------------------
  862|  3.31k|                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|  3.31k|        }
  864|     30|        else
  865|       |            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.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 (865:13): [True: 30, False: 0]
  ------------------
  866|  3.34k|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE9ParseTrueILj1ENS_25GenericInsituStringStreamIS2_EENS_15GenericDocumentIS2_NS_19MemoryPoolAllocatorIS3_EES3_EEEEvRT0_RT1_:
  869|  38.1k|    void ParseTrue(InputStream& is, Handler& handler) {
  870|  38.1k|        RAPIDJSON_ASSERT(is.Peek() == 't');
  ------------------
  |  |  437|  38.1k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (870:9): [True: 38.1k, False: 0]
  ------------------
  871|  38.1k|        is.Take();
  872|       |
  873|  38.1k|        if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) {
  ------------------
  |  |  492|   152k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 38.0k, False: 58]
  |  |  |  Branch (492:49): [True: 38.0k, False: 14]
  |  |  |  Branch (492:49): [True: 38.0k, False: 22]
  |  |  |  Branch (492:49): [True: 38.0k, False: 22]
  |  |  ------------------
  ------------------
  874|  38.0k|            if (RAPIDJSON_UNLIKELY(!handler.Bool(true)))
  ------------------
  |  |  505|  38.0k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 38.0k]
  |  |  ------------------
  ------------------
  875|  38.0k|                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|  38.0k|        }
  877|     58|        else
  878|       |            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
  ------------------
  |  |  120|    116|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     58|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|    116|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|     58|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|     58|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|     58|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|     58|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|     58|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|     58|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|     58|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|     58|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 58]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|    116|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|     58|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|    116|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|     58|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|    116|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|     58|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 58, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|    116|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|     58|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|     58|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|     58|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     58|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     58|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (878:13): [True: 58, False: 0]
  ------------------
  879|  38.1k|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE10ParseFalseILj1ENS_25GenericInsituStringStreamIS2_EENS_15GenericDocumentIS2_NS_19MemoryPoolAllocatorIS3_EES3_EEEEvRT0_RT1_:
  882|  23.6k|    void ParseFalse(InputStream& is, Handler& handler) {
  883|  23.6k|        RAPIDJSON_ASSERT(is.Peek() == 'f');
  ------------------
  |  |  437|  23.6k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (883:9): [True: 23.6k, False: 0]
  ------------------
  884|  23.6k|        is.Take();
  885|       |
  886|  23.6k|        if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) {
  ------------------
  |  |  492|   141k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 23.6k, False: 30]
  |  |  |  Branch (492:49): [True: 23.6k, False: 8]
  |  |  |  Branch (492:49): [True: 23.6k, False: 6]
  |  |  |  Branch (492:49): [True: 23.6k, False: 14]
  |  |  |  Branch (492:49): [True: 23.6k, False: 2]
  |  |  ------------------
  ------------------
  887|  23.6k|            if (RAPIDJSON_UNLIKELY(!handler.Bool(false)))
  ------------------
  |  |  505|  23.6k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 23.6k]
  |  |  ------------------
  ------------------
  888|  23.6k|                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|  23.6k|        }
  890|     30|        else
  891|       |            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.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 (891:13): [True: 30, False: 0]
  ------------------
  892|  23.6k|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE11ParseObjectILj1ENS_25GenericInsituStringStreamIS2_EENS_15GenericDocumentIS2_NS_19MemoryPoolAllocatorIS3_EES3_EEEEvRT0_RT1_:
  740|  3.75M|    void ParseObject(InputStream& is, Handler& handler) {
  741|  3.75M|        RAPIDJSON_ASSERT(is.Peek() == '{');
  ------------------
  |  |  437|  3.75M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (741:9): [True: 3.75M, False: 0]
  ------------------
  742|  3.75M|        is.Take();  // Skip '{'
  743|       |
  744|  3.75M|        if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
  ------------------
  |  |  505|  3.75M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 3.75M]
  |  |  ------------------
  ------------------
  745|  3.75M|            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.75M|        SkipWhitespaceAndComments<parseFlags>(is);
  748|  3.75M|        RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  3.75M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  3.75M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  3.75M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  3.75M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  3.75M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 3.75M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  3.75M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  3.75M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  3.75M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 3.75M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  749|       |
  750|  3.75M|        if (Consume(is, '}')) {
  ------------------
  |  Branch (750:13): [True: 2.84M, False: 917k]
  ------------------
  751|  2.84M|            if (RAPIDJSON_UNLIKELY(!handler.EndObject(0)))  // empty object
  ------------------
  |  |  505|  2.84M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 2.84M]
  |  |  ------------------
  ------------------
  752|  2.84M|                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.84M|            return;
  754|  2.84M|        }
  755|       |
  756|  3.86M|        for (SizeType memberCount = 0;;) {
  757|  3.86M|            if (RAPIDJSON_UNLIKELY(is.Peek() != '"'))
  ------------------
  |  |  505|  3.86M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 180, False: 3.86M]
  |  |  ------------------
  ------------------
  758|  3.86M|                RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell());
  ------------------
  |  |  120|    360|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|    180|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|    360|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|    180|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|    180|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|    180|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|    180|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|    180|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|    180|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|    180|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|    180|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 180]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|    360|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|    180|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|    360|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|    180|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|    360|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|    180|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 180, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|    360|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|    180|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|    180|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|    180|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|    180|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|    180|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (758:17): [True: 180, False: 0]
  ------------------
  759|       |
  760|  3.86M|            ParseString<parseFlags>(is, handler, true);
  761|  3.86M|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  3.86M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  3.86M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  3.86M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  3.86M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  3.86M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 32, False: 3.86M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  3.86M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  3.86M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  3.86M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 3.86M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  762|       |
  763|  3.86M|            SkipWhitespaceAndComments<parseFlags>(is);
  764|  3.86M|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  3.86M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  3.86M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  3.86M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  3.86M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  3.86M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 3.86M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  3.86M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  3.86M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  3.86M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 3.86M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  765|       |
  766|  3.86M|            if (RAPIDJSON_UNLIKELY(!Consume(is, ':')))
  ------------------
  |  |  505|  3.86M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 74, False: 3.86M]
  |  |  ------------------
  ------------------
  767|  3.86M|                RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());
  ------------------
  |  |  120|    148|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     74|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|    148|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|     74|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|     74|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|     74|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|     74|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|     74|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|     74|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|     74|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|     74|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 74]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|    148|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|     74|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|    148|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|     74|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|    148|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|     74|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 74, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|    148|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|     74|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|     74|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|     74|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     74|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     74|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (767:17): [True: 74, False: 0]
  ------------------
  768|       |
  769|  3.86M|            SkipWhitespaceAndComments<parseFlags>(is);
  770|  3.86M|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  3.86M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  3.86M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  3.86M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  3.86M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  3.86M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 3.86M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  3.86M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  3.86M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  3.86M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 3.86M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  771|       |
  772|  3.86M|            ParseValue<parseFlags>(is, handler);
  773|  3.86M|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  3.86M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  3.86M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  3.86M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  3.86M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  3.86M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 3.93k, False: 3.85M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  3.86M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  3.86M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  3.86M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 3.85M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  774|       |
  775|  3.85M|            SkipWhitespaceAndComments<parseFlags>(is);
  776|  3.85M|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  3.85M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  3.85M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  3.85M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  3.85M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  3.85M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 3.85M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  3.85M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  3.85M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  3.85M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 3.85M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  777|       |
  778|  3.85M|            ++memberCount;
  779|       |
  780|  3.85M|            switch (is.Peek()) {
  781|  2.94M|                case ',':
  ------------------
  |  Branch (781:17): [True: 2.94M, False: 913k]
  ------------------
  782|  2.94M|                    is.Take();
  783|  2.94M|                    SkipWhitespaceAndComments<parseFlags>(is);
  784|  2.94M|                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  2.94M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  2.94M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  2.94M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  2.94M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  2.94M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 2.94M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  2.94M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  2.94M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  2.94M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 2.94M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  785|  2.94M|                    break;
  786|  2.94M|                case '}':
  ------------------
  |  Branch (786:17): [True: 913k, False: 2.94M]
  ------------------
  787|   913k|                    is.Take();
  788|   913k|                    if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
  ------------------
  |  |  505|   913k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 913k]
  |  |  ------------------
  ------------------
  789|   913k|                        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|   913k|                    return;
  791|   913k|                default:
  ------------------
  |  Branch (791:17): [True: 70, False: 3.85M]
  ------------------
  792|     70|                    RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy
  ------------------
  |  |  120|     70|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     70|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|     70|    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|     70|    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 (792:21): [True: 70, False: 0]
  ------------------
  793|  3.85M|            }
  794|       |
  795|  2.94M|            if (parseFlags & kParseTrailingCommasFlag) {
  ------------------
  |  Branch (795:17): [Folded, False: 2.94M]
  ------------------
  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|  2.94M|        }
  804|   917k|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE10ParseArrayILj1ENS_25GenericInsituStringStreamIS2_EENS_15GenericDocumentIS2_NS_19MemoryPoolAllocatorIS3_EES3_EEEEvRT0_RT1_:
  808|  4.86M|    void ParseArray(InputStream& is, Handler& handler) {
  809|  4.86M|        RAPIDJSON_ASSERT(is.Peek() == '[');
  ------------------
  |  |  437|  4.86M|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (809:9): [True: 4.86M, False: 0]
  ------------------
  810|  4.86M|        is.Take();  // Skip '['
  811|       |
  812|  4.86M|        if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
  ------------------
  |  |  505|  4.86M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 4.86M]
  |  |  ------------------
  ------------------
  813|  4.86M|            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|  4.86M|        SkipWhitespaceAndComments<parseFlags>(is);
  816|  4.86M|        RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  4.86M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  4.86M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  4.86M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  4.86M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  4.86M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 4.86M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  4.86M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  4.86M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  4.86M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 4.86M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  817|       |
  818|  4.86M|        if (Consume(is, ']')) {
  ------------------
  |  Branch (818:13): [True: 4.25k, False: 4.86M]
  ------------------
  819|  4.25k|            if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array
  ------------------
  |  |  505|  4.25k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 4.25k]
  |  |  ------------------
  ------------------
  820|  4.25k|                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|  4.25k|            return;
  822|  4.25k|        }
  823|       |
  824|  31.5M|        for (SizeType elementCount = 0;;) {
  825|  31.5M|            ParseValue<parseFlags>(is, handler);
  826|  31.5M|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  31.5M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  31.5M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  31.5M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  31.5M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  31.5M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 4.64M, False: 26.8M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  31.5M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  31.5M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  31.5M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 26.8M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  827|       |
  828|  26.8M|            ++elementCount;
  829|  26.8M|            SkipWhitespaceAndComments<parseFlags>(is);
  830|  26.8M|            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  26.8M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  26.8M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  26.8M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  26.8M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  26.8M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 26.8M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  26.8M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  26.8M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  26.8M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 26.8M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  831|       |
  832|  26.8M|            if (Consume(is, ',')) {
  ------------------
  |  Branch (832:17): [True: 26.6M, False: 224k]
  ------------------
  833|  26.6M|                SkipWhitespaceAndComments<parseFlags>(is);
  834|  26.6M|                RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
  ------------------
  |  |   66|  26.6M|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  ------------------
  |  |  |  |   61|  26.6M|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|  26.6M|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |   62|  26.6M|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  ------------------
  |  |  |  |  |  |  505|  26.6M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (505:31): [True: 0, False: 26.6M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |   63|  26.6M|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|  26.6M|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|  26.6M|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 26.6M]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  835|  26.6M|            }
  836|   224k|            else if (Consume(is, ']')) {
  ------------------
  |  Branch (836:22): [True: 223k, False: 878]
  ------------------
  837|   223k|                if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
  ------------------
  |  |  505|   223k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 223k]
  |  |  ------------------
  ------------------
  838|   223k|                    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|   223k|                return;
  840|   223k|            }
  841|    878|            else
  842|   224k|                RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
  ------------------
  |  |  120|  1.75k|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|    878|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|  1.75k|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|    878|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|    878|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|    878|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|    878|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|    878|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|    878|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|    878|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|    878|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 878]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|  1.75k|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|    878|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|  1.75k|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|    878|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|  1.75k|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|    878|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 878, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|  1.75k|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|    878|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|    878|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|    878|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|    878|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|    878|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (842:17): [True: 878, False: 0]
  ------------------
  843|       |
  844|  26.6M|            if (parseFlags & kParseTrailingCommasFlag) {
  ------------------
  |  Branch (844:17): [Folded, False: 26.6M]
  ------------------
  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|  26.6M|        }
  853|  4.86M|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE11ParseNumberILj1ENS_25GenericInsituStringStreamIS2_EENS_15GenericDocumentIS2_NS_19MemoryPoolAllocatorIS3_EES3_EEEEvRT0_RT1_:
 1468|  26.6M|    void ParseNumber(InputStream& is, Handler& handler) {
 1469|  26.6M|        typedef typename internal::SelectIf<internal::BoolType<(parseFlags & kParseNumbersAsStringsFlag) != 0>, typename TargetEncoding::Ch, char>::Type NumberCharacter;
 1470|       |
 1471|  26.6M|        internal::StreamLocalCopy<InputStream> copy(is);
 1472|  26.6M|        NumberStream<InputStream, NumberCharacter,
 1473|  26.6M|            ((parseFlags & kParseNumbersAsStringsFlag) != 0) ?
 1474|  26.6M|                ((parseFlags & kParseInsituFlag) == 0) :
 1475|  26.6M|                ((parseFlags & kParseFullPrecisionFlag) != 0),
 1476|  26.6M|            (parseFlags & kParseNumbersAsStringsFlag) != 0 &&
 1477|  26.6M|                (parseFlags & kParseInsituFlag) == 0> s(*this, copy.s);
 1478|       |
 1479|  26.6M|        size_t startOffset = s.Tell();
 1480|  26.6M|        double d = 0.0;
 1481|  26.6M|        bool useNanOrInf = false;
 1482|       |
 1483|       |        // Parse minus
 1484|  26.6M|        bool minus = Consume(s, '-');
 1485|       |
 1486|       |        // Parse int: zero / ( digit1-9 *DIGIT )
 1487|  26.6M|        unsigned i = 0;
 1488|  26.6M|        uint64_t i64 = 0;
 1489|  26.6M|        bool use64bit = false;
 1490|  26.6M|        int significandDigit = 0;
 1491|  26.6M|        if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) {
  ------------------
  |  |  505|  26.6M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 2.17M, False: 24.4M]
  |  |  ------------------
  ------------------
 1492|  2.17M|            i = 0;
 1493|  2.17M|            s.TakePush();
 1494|  2.17M|        }
 1495|  24.4M|        else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) {
  ------------------
  |  |  492|  48.8M|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 24.4M, False: 846]
  |  |  |  Branch (492:49): [True: 24.4M, False: 714]
  |  |  |  Branch (492:49): [True: 24.4M, False: 132]
  |  |  ------------------
  ------------------
 1496|  24.4M|            i = static_cast<unsigned>(s.TakePush() - '0');
 1497|       |
 1498|  24.4M|            if (minus)
  ------------------
  |  Branch (1498:17): [True: 189k, False: 24.2M]
  ------------------
 1499|   688k|                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|  1.22M|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 527k, False: 161k]
  |  |  |  Branch (492:49): [True: 532k, False: 156k]
  |  |  |  Branch (492:49): [True: 527k, False: 4.88k]
  |  |  ------------------
  ------------------
 1500|   527k|                    if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648
  ------------------
  |  |  505|   527k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 51.6k, False: 475k]
  |  |  ------------------
  ------------------
 1501|  51.6k|                        if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) {
  ------------------
  |  |  492|  98.9k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 27.9k, False: 23.7k]
  |  |  |  Branch (492:49): [True: 4.44k, False: 47.2k]
  |  |  |  Branch (492:49): [True: 23.4k, False: 23.7k]
  |  |  ------------------
  ------------------
 1502|  27.9k|                            i64 = i;
 1503|  27.9k|                            use64bit = true;
 1504|  27.9k|                            break;
 1505|  27.9k|                        }
 1506|  51.6k|                    }
 1507|   499k|                    i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
 1508|   499k|                    significandDigit++;
 1509|   499k|                }
 1510|  24.2M|            else
 1511|  24.9M|                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|  26.5M|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 759k, False: 24.2M]
  |  |  |  Branch (492:49): [True: 1.61M, False: 23.3M]
  |  |  |  Branch (492:49): [True: 759k, False: 854k]
  |  |  ------------------
  ------------------
 1512|   759k|                    if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295
  ------------------
  |  |  505|   759k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 23.4k, False: 735k]
  |  |  ------------------
  ------------------
 1513|  23.4k|                        if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) {
  ------------------
  |  |  492|  29.2k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 21.2k, False: 2.20k]
  |  |  |  Branch (492:49): [True: 17.7k, False: 5.71k]
  |  |  |  Branch (492:49): [True: 3.51k, False: 2.20k]
  |  |  ------------------
  ------------------
 1514|  21.2k|                            i64 = i;
 1515|  21.2k|                            use64bit = true;
 1516|  21.2k|                            break;
 1517|  21.2k|                        }
 1518|  23.4k|                    }
 1519|   737k|                    i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
 1520|   737k|                    significandDigit++;
 1521|   737k|                }
 1522|  24.4M|        }
 1523|       |        // Parse NaN or Infinity here
 1524|    846|        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: 846]
  ------------------
 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|    846|        else
 1548|    846|            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
  ------------------
  |  |  120|  1.69k|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|    846|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|  1.69k|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|    846|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|    846|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|    846|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|    846|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|    846|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|    846|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|    846|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|    846|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 846]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|  1.69k|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|    846|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|  1.69k|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|    846|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|  1.69k|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|    846|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 846, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|  1.69k|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|    846|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|    846|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|    846|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|    846|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|    846|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1548:13): [True: 846, False: 0]
  ------------------
 1549|       |
 1550|       |        // Parse 64bit int
 1551|  26.6M|        bool useDouble = false;
 1552|  26.6M|        if (use64bit) {
  ------------------
  |  Branch (1552:13): [True: 49.1k, False: 26.5M]
  ------------------
 1553|  49.1k|            if (minus)
  ------------------
  |  Branch (1553:17): [True: 27.9k, False: 21.2k]
  ------------------
 1554|  71.9k|                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|   117k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 44.9k, False: 26.9k]
  |  |  |  Branch (492:49): [True: 45.2k, False: 26.6k]
  |  |  |  Branch (492:49): [True: 44.9k, False: 306]
  |  |  ------------------
  ------------------
 1555|  44.9k|                     if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808
  ------------------
  |  |  505|  44.9k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 1.25k, False: 43.7k]
  |  |  ------------------
  ------------------
 1556|  1.25k|                        if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) {
  ------------------
  |  |  492|  2.03k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 971, False: 287]
  |  |  |  Branch (492:49): [True: 477, False: 781]
  |  |  |  Branch (492:49): [True: 494, False: 287]
  |  |  ------------------
  ------------------
 1557|    971|                            d = static_cast<double>(i64);
 1558|    971|                            useDouble = true;
 1559|    971|                            break;
 1560|    971|                        }
 1561|  44.0k|                    i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
 1562|  44.0k|                    significandDigit++;
 1563|  44.0k|                }
 1564|  21.2k|            else
 1565|   141k|                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|   268k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 123k, False: 18.0k]
  |  |  |  Branch (492:49): [True: 127k, False: 14.0k]
  |  |  |  Branch (492:49): [True: 123k, False: 3.93k]
  |  |  ------------------
  ------------------
 1566|   123k|                    if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615
  ------------------
  |  |  505|   123k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 4.34k, False: 119k]
  |  |  ------------------
  ------------------
 1567|  4.34k|                        if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) {
  ------------------
  |  |  492|  5.69k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 3.27k, False: 1.06k]
  |  |  |  Branch (492:49): [True: 2.99k, False: 1.35k]
  |  |  |  Branch (492:49): [True: 286, False: 1.06k]
  |  |  ------------------
  ------------------
 1568|  3.27k|                            d = static_cast<double>(i64);
 1569|  3.27k|                            useDouble = true;
 1570|  3.27k|                            break;
 1571|  3.27k|                        }
 1572|   120k|                    i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
 1573|   120k|                    significandDigit++;
 1574|   120k|                }
 1575|  49.1k|        }
 1576|       |
 1577|       |        // Force double for big integer
 1578|  26.6M|        if (useDouble) {
  ------------------
  |  Branch (1578:13): [True: 4.24k, False: 26.5M]
  ------------------
 1579|  49.9k|            while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|  96.2k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 45.6k, False: 4.24k]
  |  |  |  Branch (492:49): [True: 46.3k, False: 3.54k]
  |  |  |  Branch (492:49): [True: 45.6k, False: 707]
  |  |  ------------------
  ------------------
 1580|  45.6k|                d = d * 10 + (s.TakePush() - '0');
 1581|  45.6k|            }
 1582|  4.24k|        }
 1583|       |
 1584|       |        // Parse frac = decimal-point 1*DIGIT
 1585|  26.6M|        int expFrac = 0;
 1586|  26.6M|        size_t decimalPosition;
 1587|  26.6M|        if (Consume(s, '.')) {
  ------------------
  |  Branch (1587:13): [True: 494k, False: 26.1M]
  ------------------
 1588|   494k|            decimalPosition = s.Length();
 1589|       |
 1590|   494k|            if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9')))
  ------------------
  |  |  505|   989k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 6, False: 494k]
  |  |  |  Branch (505:51): [True: 494k, False: 2]
  |  |  |  Branch (505:51): [True: 494k, False: 4]
  |  |  ------------------
  ------------------
 1591|   494k|                RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell());
  ------------------
  |  |  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 (1591:17): [True: 6, False: 0]
  ------------------
 1592|       |
 1593|   494k|            if (!useDouble) {
  ------------------
  |  Branch (1593:17): [True: 494k, False: 282]
  ------------------
 1594|   494k|#if RAPIDJSON_64BIT
 1595|       |                // Use i64 to store significand in 64-bit architecture
 1596|   494k|                if (!use64bit)
  ------------------
  |  Branch (1596:21): [True: 493k, False: 853]
  ------------------
 1597|   493k|                    i64 = i;
 1598|       |
 1599|  3.63M|                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|  6.91M|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 3.14M, False: 492k]
  |  |  |  Branch (492:49): [True: 3.27M, False: 358k]
  |  |  |  Branch (492:49): [True: 3.14M, False: 133k]
  |  |  ------------------
  ------------------
 1600|  3.14M|                    if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path
  ------------------
  |  |  320|  3.14M|#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  ------------------
  |  Branch (1600:25): [True: 2.13k, False: 3.14M]
  ------------------
 1601|  2.13k|                        break;
 1602|  3.14M|                    else {
 1603|  3.14M|                        i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
 1604|  3.14M|                        --expFrac;
 1605|  3.14M|                        if (i64 != 0)
  ------------------
  |  Branch (1605:29): [True: 1.66M, False: 1.47M]
  ------------------
 1606|  1.66M|                            significandDigit++;
 1607|  3.14M|                    }
 1608|  3.14M|                }
 1609|       |
 1610|   494k|                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|   494k|                useDouble = true;
 1616|   494k|            }
 1617|       |
 1618|  3.63M|            while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|  6.90M|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 3.14M, False: 494k]
  |  |  |  Branch (492:49): [True: 3.27M, False: 360k]
  |  |  |  Branch (492:49): [True: 3.14M, False: 134k]
  |  |  ------------------
  ------------------
 1619|  3.14M|                if (significandDigit < 17) {
  ------------------
  |  Branch (1619:21): [True: 1.76k, False: 3.13M]
  ------------------
 1620|  1.76k|                    d = d * 10.0 + (s.TakePush() - '0');
 1621|  1.76k|                    --expFrac;
 1622|  1.76k|                    if (RAPIDJSON_LIKELY(d > 0.0))
  ------------------
  |  |  492|  1.76k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 1.76k, False: 0]
  |  |  ------------------
  ------------------
 1623|  1.76k|                        significandDigit++;
 1624|  1.76k|                }
 1625|  3.13M|                else
 1626|  3.13M|                    s.TakePush();
 1627|  3.14M|            }
 1628|   494k|        }
 1629|  26.1M|        else
 1630|  26.1M|            decimalPosition = s.Length(); // decimal position at the end of integer.
 1631|       |
 1632|       |        // Parse exp = e [ minus / plus ] 1*DIGIT
 1633|  26.6M|        int exp = 0;
 1634|  26.6M|        if (Consume(s, 'e') || Consume(s, 'E')) {
  ------------------
  |  Branch (1634:13): [True: 64.5k, False: 26.5M]
  |  Branch (1634:32): [True: 3.94k, False: 26.5M]
  ------------------
 1635|  68.5k|            if (!useDouble) {
  ------------------
  |  Branch (1635:17): [True: 7.25k, False: 61.2k]
  ------------------
 1636|  7.25k|                d = static_cast<double>(use64bit ? i64 : i);
  ------------------
  |  Branch (1636:41): [True: 671, False: 6.58k]
  ------------------
 1637|  7.25k|                useDouble = true;
 1638|  7.25k|            }
 1639|       |
 1640|  68.5k|            bool expMinus = false;
 1641|  68.5k|            if (Consume(s, '+'))
  ------------------
  |  Branch (1641:17): [True: 532, False: 67.9k]
  ------------------
 1642|    532|                ;
 1643|  67.9k|            else if (Consume(s, '-'))
  ------------------
  |  Branch (1643:22): [True: 63.4k, False: 4.49k]
  ------------------
 1644|  63.4k|                expMinus = true;
 1645|       |
 1646|  68.5k|            if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|   136k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 68.4k, False: 48]
  |  |  |  Branch (492:49): [True: 68.4k, False: 36]
  |  |  |  Branch (492:49): [True: 68.4k, False: 12]
  |  |  ------------------
  ------------------
 1647|  68.4k|                exp = static_cast<int>(s.Take() - '0');
 1648|  68.4k|                if (expMinus) {
  ------------------
  |  Branch (1648:21): [True: 63.4k, False: 4.98k]
  ------------------
 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|  63.4k|                    RAPIDJSON_ASSERT(expFrac <= 0);
  ------------------
  |  |  437|  63.4k|#define RAPIDJSON_ASSERT(x) assert(x)
  ------------------
  |  Branch (1655:21): [True: 63.4k, False: 0]
  ------------------
 1656|  63.4k|                    int maxExp = (expFrac + 2147483639) / 10;
 1657|       |
 1658|  83.7k|                    while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|   105k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 20.2k, False: 63.4k]
  |  |  |  Branch (492:49): [True: 22.1k, False: 61.6k]
  |  |  |  Branch (492:49): [True: 20.2k, False: 1.85k]
  |  |  ------------------
  ------------------
 1659|  20.2k|                        exp = exp * 10 + static_cast<int>(s.Take() - '0');
 1660|  20.2k|                        if (RAPIDJSON_UNLIKELY(exp > maxExp)) {
  ------------------
  |  |  505|  20.2k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 311, False: 19.9k]
  |  |  ------------------
  ------------------
 1661|    877|                            while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9'))  // Consume the rest of exponent
  ------------------
  |  |  505|  1.45k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 566, False: 311]
  |  |  |  Branch (505:51): [True: 577, False: 300]
  |  |  |  Branch (505:51): [True: 566, False: 11]
  |  |  ------------------
  ------------------
 1662|    566|                                s.Take();
 1663|    311|                        }
 1664|  20.2k|                    }
 1665|  63.4k|                }
 1666|  4.98k|                else {  // positive exp
 1667|  4.98k|                    int maxExp = 308 - expFrac;
 1668|  6.04k|                    while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
  ------------------
  |  |  492|  7.15k|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 1.06k, False: 4.97k]
  |  |  |  Branch (492:49): [True: 1.10k, False: 4.94k]
  |  |  |  Branch (492:49): [True: 1.06k, False: 34]
  |  |  ------------------
  ------------------
 1669|  1.06k|                        exp = exp * 10 + static_cast<int>(s.Take() - '0');
 1670|  1.06k|                        if (RAPIDJSON_UNLIKELY(exp > maxExp))
  ------------------
  |  |  505|  1.06k|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 2, False: 1.06k]
  |  |  ------------------
  ------------------
 1671|  1.06k|                            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|  1.06k|                    }
 1673|  4.98k|                }
 1674|  68.4k|            }
 1675|     48|            else
 1676|  68.5k|                RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell());
  ------------------
  |  |  120|     96|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  ------------------
  |  |  |  |  516|     48|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  ------------------
  |  |  121|     96|    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
  |  |  ------------------
  |  |  |  |  101|     48|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  ------------------
  |  |  |  |  |  |  516|     48|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  ------------------
  |  |  |  |  102|     48|    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
  |  |  |  |  ------------------
  |  |  |  |  |  |  437|     48|#define RAPIDJSON_ASSERT(x) assert(x)
  |  |  |  |  ------------------
  |  |  |  |  103|     48|    SetParseError(parseErrorCode, offset); \
  |  |  |  |  104|     48|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  ------------------
  |  |  |  |  |  |  517|     48|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  518|     48|} while((void)0, 0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 48]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  122|     96|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
  |  |  ------------------
  |  |  |  |   66|     48|    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  |  |  |  |  ------------------
  |  |  |  |  |  |   61|     96|    RAPIDJSON_MULTILINEMACRO_BEGIN \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  516|     48|#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   62|     96|    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  505|     48|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (505:31): [True: 48, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   63|     96|    RAPIDJSON_MULTILINEMACRO_END
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  517|     48|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  |  |  |  |  518|     48|} while((void)0, 0)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  123|     48|    RAPIDJSON_MULTILINEMACRO_END
  |  |  ------------------
  |  |  |  |  517|     48|#define RAPIDJSON_MULTILINEMACRO_END \
  |  |  |  |  518|     48|} while((void)0, 0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (518:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1676:17): [True: 48, False: 0]
  ------------------
 1677|       |
 1678|  68.4k|            if (expMinus)
  ------------------
  |  Branch (1678:17): [True: 63.4k, False: 4.97k]
  ------------------
 1679|  63.4k|                exp = -exp;
 1680|  68.4k|        }
 1681|       |
 1682|       |        // Finish parsing, call event according to the type of number.
 1683|  26.6M|        bool cont = true;
 1684|       |
 1685|  26.6M|        if (parseFlags & kParseNumbersAsStringsFlag) {
  ------------------
  |  Branch (1685:13): [Folded, False: 26.6M]
  ------------------
 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.6M|        else {
 1709|  26.6M|           size_t length = s.Length();
 1710|  26.6M|           const NumberCharacter* decimal = s.Pop();  // Pop stack no matter if it will be used or not.
 1711|       |
 1712|  26.6M|           if (useDouble) {
  ------------------
  |  Branch (1712:16): [True: 506k, False: 26.0M]
  ------------------
 1713|   506k|               int p = exp + expFrac;
 1714|   506k|               if (parseFlags & kParseFullPrecisionFlag)
  ------------------
  |  Branch (1714:20): [Folded, False: 506k]
  ------------------
 1715|      0|                   d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp);
 1716|   506k|               else
 1717|   506k|                   d = internal::StrtodNormalPrecision(d, p);
 1718|       |
 1719|       |               // Use > max, instead of == inf, to fix bogus warning -Wfloat-equal
 1720|   506k|               if (d > (std::numeric_limits<double>::max)()) {
  ------------------
  |  Branch (1720:20): [True: 2, False: 506k]
  ------------------
 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|   506k|               cont = handler.Double(minus ? -d : d);
  ------------------
  |  Branch (1726:38): [True: 100k, False: 406k]
  ------------------
 1727|   506k|           }
 1728|  26.0M|           else if (useNanOrInf) {
  ------------------
  |  Branch (1728:21): [True: 0, False: 26.0M]
  ------------------
 1729|      0|               cont = handler.Double(d);
 1730|      0|           }
 1731|  26.0M|           else {
 1732|  26.0M|               if (use64bit) {
  ------------------
  |  Branch (1732:20): [True: 43.4k, False: 26.0M]
  ------------------
 1733|  43.4k|                   if (minus)
  ------------------
  |  Branch (1733:24): [True: 26.7k, False: 16.6k]
  ------------------
 1734|  26.7k|                       cont = handler.Int64(static_cast<int64_t>(~i64 + 1));
 1735|  16.6k|                   else
 1736|  16.6k|                       cont = handler.Uint64(i64);
 1737|  43.4k|               }
 1738|  26.0M|               else {
 1739|  26.0M|                   if (minus)
  ------------------
  |  Branch (1739:24): [True: 78.4k, False: 25.9M]
  ------------------
 1740|  78.4k|                       cont = handler.Int(static_cast<int32_t>(~i + 1));
 1741|  25.9M|                   else
 1742|  25.9M|                       cont = handler.Uint(i);
 1743|  26.0M|               }
 1744|  26.0M|           }
 1745|  26.6M|        }
 1746|  26.6M|        if (RAPIDJSON_UNLIKELY(!cont))
  ------------------
  |  |  505|  26.6M|#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (505:31): [True: 0, False: 26.6M]
  |  |  ------------------
  ------------------
 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.6M|    }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE12NumberStreamINS_25GenericInsituStringStreamIS2_EEcLb0ELb0EE4TellEv:
 1422|  26.6M|        size_t Tell() { return is.Tell(); }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE7ConsumeINS4_12NumberStreamINS_25GenericInsituStringStreamIS2_EEcLb0ELb0EEEEEbRT_NSA_2ChE:
  895|   106M|    RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) {
  896|   106M|        if (RAPIDJSON_LIKELY(is.Peek() == expect)) {
  ------------------
  |  |  492|   106M|#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (492:29): [True: 832k, False: 105M]
  |  |  ------------------
  ------------------
  897|   832k|            is.Take();
  898|   832k|            return true;
  899|   832k|        }
  900|   105M|        else
  901|   105M|            return false;
  902|   106M|    }
_ZNK9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE12NumberStreamINS_25GenericInsituStringStreamIS2_EEcLb0ELb0EE4PeekEv:
 1417|   225M|        RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE12NumberStreamINS_25GenericInsituStringStreamIS2_EEcLb0ELb0EE8TakePushEv:
 1418|  34.3M|        RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE12NumberStreamINS_25GenericInsituStringStreamIS2_EEcLb0ELb0EE6LengthEv:
 1423|  53.2M|        size_t Length() { return 0; }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE12NumberStreamINS_25GenericInsituStringStreamIS2_EEcLb0ELb0EE4TakeEv:
 1419|   923k|        RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE12NumberStreamINS_25GenericInsituStringStreamIS2_EEcLb0ELb0EE3PopEv:
 1424|  26.6M|        const StackCharacter* Pop() { return 0; }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEEC2EPS3_m:
  548|  8.06k|        stack_(stackAllocator, stackCapacity), parseResult_(), state_(IterativeParsingStartState) {}
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE16ClearStackOnExitC2ERS4_:
  702|  8.06k|        explicit ClearStackOnExit(GenericReader& r) : r_(r) {}
_ZN9rapidjson8internal15StreamLocalCopyINS_25GenericInsituStringStreamINS_4UTF8IcEEEELi1EEC2ERS5_:
  233|   107M|    StreamLocalCopy(Stream& original) : s(original), original_(original) {}
_ZN9rapidjson8internal15StreamLocalCopyINS_25GenericInsituStringStreamINS_4UTF8IcEEEELi1EED2Ev:
  234|   107M|    ~StreamLocalCopy() { original_ = s; }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE12NumberStreamINS_25GenericInsituStringStreamIS2_EEcLb0ELb0EEC2ERS4_RS7_:
 1415|  26.6M|        NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader;  }
_ZN9rapidjson13GenericReaderINS_4UTF8IcEES2_NS_12CrtAllocatorEE16ClearStackOnExitD2Ev:
  703|  8.06k|        ~ClearStackOnExit() { r_.ClearStack(); }

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

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

_ZN10AssimpFuzz11ForceFormatERN6Assimp8ImporterEPKc:
   53|  3.24k|inline bool ForceFormat(Assimp::Importer& importer, const char* targetExtension) {
   54|  3.24k|    size_t count = importer.GetImporterCount();
   55|  3.24k|    std::vector<Assimp::BaseImporter*> toRemove;
   56|  3.24k|    bool found = false;
   57|       |
   58|   158k|    for (size_t i = 0; i < count; ++i) {
  ------------------
  |  Branch (58:24): [True: 155k, False: 3.24k]
  ------------------
   59|   155k|        const aiImporterDesc* desc = importer.GetImporterInfo(i);
   60|   155k|        Assimp::BaseImporter* imp = importer.GetImporter(i);
   61|       |        
   62|   155k|        if (!desc || !imp) continue;
  ------------------
  |  Branch (62:13): [True: 0, False: 155k]
  |  Branch (62:22): [True: 0, False: 155k]
  ------------------
   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|   155k|        bool isTarget = false;
   72|   155k|        const char* extList = desc->mFileExtensions;
   73|   155k|        if (!extList) {
  ------------------
  |  Branch (73:13): [True: 0, False: 155k]
  ------------------
   74|      0|            toRemove.push_back(imp);
   75|      0|            continue;
   76|      0|        }
   77|   155k|        const size_t targetLen = strlen(targetExtension);
   78|       |
   79|   155k|        const char* p = extList;
   80|   155k|        while ((p = strstr(p, targetExtension)) != nullptr) {
  ------------------
  |  Branch (80:16): [True: 6.48k, False: 149k]
  ------------------
   81|       |            // Check boundaries
   82|  6.48k|            const char prev = (p == extList) ? ' ' : *(p - 1);
  ------------------
  |  Branch (82:31): [True: 0, False: 6.48k]
  ------------------
   83|  6.48k|            const char next = *(p + targetLen);
   84|       |            
   85|  6.48k|            if (prev == ' ' && (next == ' ' || next == '\0')) {
  ------------------
  |  Branch (85:17): [True: 6.48k, False: 0]
  |  Branch (85:33): [True: 3.24k, False: 3.24k]
  |  Branch (85:48): [True: 3.24k, False: 0]
  ------------------
   86|  6.48k|                isTarget = true;
   87|  6.48k|                break;
   88|  6.48k|            }
   89|      0|            p++;
   90|      0|        }
   91|       |
   92|   155k|        if (isTarget) {
  ------------------
  |  Branch (92:13): [True: 6.48k, False: 149k]
  ------------------
   93|  6.48k|            found = true;
   94|   149k|        } else {
   95|   149k|            toRemove.push_back(imp);
   96|   149k|        }
   97|   155k|    }
   98|       |
   99|   149k|    for (auto* imp : toRemove) {
  ------------------
  |  Branch (99:20): [True: 149k, False: 3.24k]
  ------------------
  100|   149k|        importer.UnregisterLoader(imp);
  101|   149k|        delete imp;  // Free the unregistered importer to prevent memory leaks
  102|   149k|    }
  103|       |
  104|  3.24k|    return found;
  105|  3.24k|}

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

