Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Loading a 3D model from Qt Resources. Assimp Error: No suitable reader found for the file format of file "$$$___magic___$$$.".
Forum Updated to NodeBB v4.3 + New Features

Loading a 3D model from Qt Resources. Assimp Error: No suitable reader found for the file format of file "$$$___magic___$$$.".

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 4 Posters 1.8k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • 8Observer88 Offline
    8Observer88 Offline
    8Observer8
    wrote on last edited by 8Observer8
    #1

    Hello. I want to load a simple 3D model (just plane.dae) from Qt resources. But I get this error: Assimp Error: No suitable reader found for the file format of file "$$$___magic___$$$.".

    // Add these lines to .pro:
    // INCLUDEPATH += "E:\Libs\assimp-5.0.1-mingw-32bit\include"
    // LIBS += -L"E:\Libs\assimp-5.0.1-mingw-32bit\lib"
    // LIBS += -lopengl32 -lassimp -lIrrXML -lzlibstatic
    
    #ifdef _WIN32
    #include <windows.h>
    extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
    extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
    #endif
    
    #include <QtWidgets/QApplication>
    #include <QtWidgets/QOpenGLWidget>
    #include <QtCore/QResource>
    #include <QtCore/QDebug>
    #include "assimp/Importer.hpp"
    #include <assimp/scene.h>
    #include <assimp/postprocess.h>
    
    class OpenGLWidget : public QOpenGLWidget {
    public:
        OpenGLWidget(QWidget *parent = nullptr) : QOpenGLWidget (parent) {}
    private:
        void initializeGL() override {
            glClearColor(0.f, 0.f, 0.f, 1.f);
            glEnable(GL_DEPTH_TEST);
    
            Assimp::Importer importer;
            QResource r(":/Models/PlaneBlender8.dae");
    
            // const aiScene *scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);
            const aiScene *scene = importer.ReadFileFromMemory(r.data(), r.size(),
                                                               aiProcess_Triangulate | aiProcess_FlipUVs);
    
            if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
                qDebug() << "Assimp Error:" << importer.GetErrorString();
                return;
            }
        }
        void resizeGL(int w, int h) override {
            glViewport(0, 0, w, h);
        }
        void paintGL() override {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        }
    };
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        OpenGLWidget w;
        w.show();
        return a.exec();
    }
    
    1 Reply Last reply
    0
    • B Offline
      B Offline
      Bonnie
      wrote on last edited by Bonnie
      #2

      How do you add PlaneBlender8.dae to your resource?
      Is PlaneBlender8.dae a compressed file created by rcc?
      Anyway that's not the right way to read from your resource.
      Use QFile to open and read it, not QResource.

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        Beside the point of @Bonnie, Qt3D integrates assimp to load 3D models.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • 8Observer88 Offline
          8Observer88 Offline
          8Observer8
          wrote on last edited by 8Observer8
          #4

          I added it by Resource Editor like usual. Okay, you are right. I will use QFile. Yes, I know about Qt3D, and maybe I will continue to study it, but pure OpenGL has more power. Really I do not like Assimp because it require additional space and I do not know how to deploy it on Phones. I will study Assimp a little because it allow to make short examples for beginners and maybe some customers will prefere Assimp. The better solution is to use .dae (Collada) because it can contain materials and any kind of animations. I like to study linear algebra of skeletal animation.

          Fuller version in WebGL: ch09/JointModel: https://jsfiddle.net/8Observer8/ygvk7odv/ (Click on Robot to control it by keys) I do not what to study deep engines like Qt3D, Unity, Unreal, Godot and so on because engines require a lot of power and space and some of them are not so fast and compact like Qt C++. I want to have three versions: Desktop, Mobile and Web. Yes, I know that some engines can build to WebGL. I tryed it with Unity, but build is havy for notebooks and does not works on mobile browsers. I do not require PBR in by 3D applications. But I study WebGL and OpenGL more than 3 years and I like it. Code in Qt C++ and WebGL is the same. I do not have time to learn something new from scratch. OpenGL and WebGL are fast, small and I have full control with shaders and math and I understand how it works. Simple games are just for practice and for fun. I want to make 3D interactive apps for non-game applications.
          JointModel_OpenGLES20_Qt5Cpp.gif

          PlaneBlender8.dae

          <?xml version="1.0" encoding="utf-8"?>
          <COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <asset>
              <contributor>
                <author>Blender User</author>
                <authoring_tool>Blender 2.83.5 commit date:2020-08-19, commit time:06:07, hash:c2b144df395f</authoring_tool>
              </contributor>
              <created>2020-11-27T14:01:41</created>
              <modified>2020-11-27T14:01:41</modified>
              <unit name="meter" meter="1"/>
              <up_axis>Z_UP</up_axis>
            </asset>
            <library_images/>
            <library_geometries>
              <geometry id="Plane-mesh" name="Plane">
                <mesh>
                  <source id="Plane-mesh-positions">
                    <float_array id="Plane-mesh-positions-array" count="12">-1 -1 0 1 -1 0 -1 1 0 1 1 0</float_array>
                    <technique_common>
                      <accessor source="#Plane-mesh-positions-array" count="4" stride="3">
                        <param name="X" type="float"/>
                        <param name="Y" type="float"/>
                        <param name="Z" type="float"/>
                      </accessor>
                    </technique_common>
                  </source>
                  <source id="Plane-mesh-normals">
                    <float_array id="Plane-mesh-normals-array" count="3">0 0 1</float_array>
                    <technique_common>
                      <accessor source="#Plane-mesh-normals-array" count="1" stride="3">
                        <param name="X" type="float"/>
                        <param name="Y" type="float"/>
                        <param name="Z" type="float"/>
                      </accessor>
                    </technique_common>
                  </source>
                  <source id="Plane-mesh-map-0">
                    <float_array id="Plane-mesh-map-0-array" count="12">1 0 0 1 0 0 1 0 1 1 0 1</float_array>
                    <technique_common>
                      <accessor source="#Plane-mesh-map-0-array" count="6" stride="2">
                        <param name="S" type="float"/>
                        <param name="T" type="float"/>
                      </accessor>
                    </technique_common>
                  </source>
                  <vertices id="Plane-mesh-vertices">
                    <input semantic="POSITION" source="#Plane-mesh-positions"/>
                  </vertices>
                  <triangles count="2">
                    <input semantic="VERTEX" source="#Plane-mesh-vertices" offset="0"/>
                    <input semantic="NORMAL" source="#Plane-mesh-normals" offset="1"/>
                    <input semantic="TEXCOORD" source="#Plane-mesh-map-0" offset="2" set="0"/>
                    <p>1 0 0 2 0 1 0 0 2 1 0 3 3 0 4 2 0 5</p>
                  </triangles>
                </mesh>
              </geometry>
            </library_geometries>
            <library_visual_scenes>
              <visual_scene id="Scene" name="Scene">
                <node id="Plane" name="Plane" type="NODE">
                  <matrix sid="transform">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix>
                  <instance_geometry url="#Plane-mesh" name="Plane"/>
                </node>
              </visual_scene>
            </library_visual_scenes>
            <scene>
              <instance_visual_scene url="#Scene"/>
            </scene>
          </COLLADA>
          
          1 Reply Last reply
          0
          • 8Observer88 Offline
            8Observer88 Offline
            8Observer8
            wrote on last edited by 8Observer8
            #5

            Loading a plane from .dae using Assimp in Qt C++ and OpenGL

            19d037e1-4da3-48c2-a2b8-352a0942cefd-image.png

            afc3f32d-5cb0-4838-95ee-893a64bb53c6-image.png

            main.cpp

            // Add these lines to .pro:
            // INCLUDEPATH += "E:\Libs\assimp-5.0.1-mingw-32bit\include"
            // LIBS += -L"E:\Libs\assimp-5.0.1-mingw-32bit\lib"
            // LIBS += -lopengl32 -lassimp -lIrrXML -lzlibstatic
            
            #ifdef _WIN32
            #include <windows.h>
            extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
            extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
            #endif
            
            #include <QtWidgets/QApplication>
            #include <QtWidgets/QOpenGLWidget>
            #include <QtWidgets/QMessageBox>
            #include <QtGui/QOpenGLBuffer>
            #include <QtGui/QOpenGLShaderProgram>
            #include <QtGui/QMatrix4x4>
            #include <QtGui/QVector3D>
            #include <QtCore/QDebug>
            #include "assimp/Importer.hpp"
            #include <assimp/scene.h>
            #include <assimp/postprocess.h>
            
            class OpenGLWidget : public QOpenGLWidget {
            public:
                OpenGLWidget(QWidget *parent = nullptr) : QOpenGLWidget (parent) {
                    setWindowTitle("Qt C++, OpenGL");
                    resize(300, 300);
                }
            private:
                QOpenGLBuffer m_vertPosBuffer;
                QOpenGLShaderProgram m_program;
                int m_numVertices;
                void initializeGL() override {
                    glClearColor(0.1f, 0.1f, 0.1f, 1.f);
                    glEnable(GL_DEPTH_TEST);
                    Assimp::Importer importer;
                    const char *path = "Models/PlaneBlender8.dae";
                    const aiScene *scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);
                    if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
                        qDebug() << "Assimp Error:" << importer.GetErrorString();
                        QMessageBox::critical(this, "Assimp Error:", importer.GetErrorString());
                        return;
                    }
                    m_numVertices = scene->mMeshes[0]->mNumVertices;
                    float vertPositions[m_numVertices * 3];
                    int vertPosIndex = 0;
                    for (int i = 0; i < m_numVertices; i++) {
                        vertPositions[vertPosIndex++] = scene->mMeshes[0]->mVertices[i].x;
                        vertPositions[vertPosIndex++] = scene->mMeshes[0]->mVertices[i].y;
                        vertPositions[vertPosIndex++] = scene->mMeshes[0]->mVertices[i].z;
            //            qDebug() << scene->mMeshes[0]->mVertices[i].x << ", "
            //                     << scene->mMeshes[0]->mVertices[i].y << ", "
            //                     << scene->mMeshes[0]->mVertices[i].z;
                    }
                    m_vertPosBuffer.create();
                    m_vertPosBuffer.bind();
                    m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));
                    const char *vertShaderSrc =
                            "#version 330 core\n"
                            "in vec3 aPosition;"
                            "uniform mat4 uModelMatrix;"
                            "void main()"
                            "{"
                            "    gl_Position = uModelMatrix * vec4(aPosition, 1.0);"
                            "}";
                    const char *fragShaderSrc =
                            "#version 330 core\n"
                            "out vec4 fragColor;"
                            "void main()"
                            "{"
                            "    fragColor = vec4(0.5, 0.2, 0.7, 1.0);"
                            "}";
                    m_program.create();
                    m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
                    m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
                    m_program.link();
                    QMatrix4x4 modelMatrix;
                    modelMatrix.scale(0.5);
                    m_program.bind();
                    m_program.setUniformValue("uModelMatrix", modelMatrix);
                    m_program.setAttributeBuffer("aPosition", GL_FLOAT, 0, 3);
                    m_program.enableAttributeArray("aPosition");
                }
                void resizeGL(int w, int h) override {
                    glViewport(0, 0, w, h);
                }
                void paintGL() override {
                    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                    glDrawArrays(GL_TRIANGLES, 0, m_numVertices);
                }
            };
            
            int main(int argc, char *argv[]) {
                QApplication a(argc, argv);
                OpenGLWidget w;
                w.show();
                return a.exec();
            }
            
            1 Reply Last reply
            0
            • 8Observer88 Offline
              8Observer88 Offline
              8Observer8
              wrote on last edited by
              #6

              I translated the example above from Qt5 to Qt6: https://github.com/8Observer8/load-with-assimp-opengl2-qt6-cpp

              1 Reply Last reply
              0
              • 8Observer88 8Observer8 referenced this topic on
              • A Offline
                A Offline
                AustinMooreT42
                wrote on last edited by
                #7

                I'm having this same issue. I get the same $$magic$$ error as well. I tried passing a .stl hint to assimp importer, but that didn't work either.
                I have a lot of stl files included using qresources, so it would be a pain to migrate away, but it is feasible. I was using Qt3D before, but am trying to get away from it since it's being deprecated. Hoping someone here has some hints.

                const auto qrc = QResource{filePath.string().c_str()};
                auto qfile     = QFile{qrc.fileName()};
                qfile.open(QIODeviceBase::OpenModeFlag::ReadOnly);
                auto data = std::vector<char>{};
                data.resize(qfile.size());
                qfile.read(data.data(), data.size());
                const auto ret = importer.ReadFileFromMemory(
                                reinterpret_cast<const void*>(data.data()), static_cast<std::size_t>(data.size()),
                                aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_FlipUVs);
                qWarning() << importer.GetErrorString();
                return ret;
                
                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved