在 QtCreator 中导入 OBJ 文件

Importing OBJ file in QtCreator

我刚开始使用 Qt Creator(版本 4.10.0,基于 Qt 5.13.1)。我已经使用了 customitemgraph example,我想用新文件替换现有的 .obj 文件。 我从网上下载了一些免费模型。其中一些有效,但其他无效。

举两个例子。

用记事本打开的 .obj 文件的摘录,可以正常工作

...
vn 0.3531 -0.8627 -0.3620
vn 0.3815 -0.9243 -0.0148
usemtl Default_OBJ
s 1
f 1/1/1 2/2/2 3/3/3 4/4/4
f 2/2/2 5/5/5 6/6/6 3/3/3
f 4/4/4 3/3/3 7/7/7 8/8/8
...

一个不工作的案例:

...
vn -0.1013 -0.8959 -0.4325
vn -0.1003 -0.8978 -0.4287
usemtl Body
s 1
f 225536//133387 225537//133388 225544//133389 225543//133390
f 225537//133388 225538//133391 225545//133392 225544//133389
f 225538//133391 225539//133393 225546//133394 225545//133392
f 225539//133393 225540//133395 225547//133396 225546//133394
...

当它不起作用时,错误消息是:

tot 4ASSERT failure in QVector<T>::operator[]: "index out of range", file c:\Users\qt\work\install\include/QtCore/qvector.h, line 448

我试过的

我用记事本打开了 .obj 文件,发现在工作情况下只有一个 / 字符分隔数字,在不工作情况下有 //两条斜杠之间没有数字。用单斜杠替换双斜杠后没有任何变化,问题继续出现。

我尝试了一些取自 here 的简单 .obj 文件来进一步诊断问题,但这些示例中的 none 有效。

我错过了什么吗?有没有解决的办法?在此示例中使用我的 .obj 文件的另一种方法?感谢您的帮助。

关于:

I've tried some simple .obj files taken from here to diagnose the problem further but none of these examples works.

我也从 here 中提取了示例 – cube.obj:

# This cube has a different material
# applied to each of its faces.
mtllib master.mtl
v 0.000000 2.000000 2.000000
v 0.000000 0.000000 2.000000
v 2.000000 0.000000 2.000000
v 2.000000 2.000000 2.000000
v 0.000000 2.000000 0.000000
v 0.000000 0.000000 0.000000
v 2.000000 0.000000 0.000000
v 2.000000 2.000000 0.000000
# 8 vertices
g front
usemtl red
f 1 2 3 4
g back
usemtl blue
f 8 7 6 5
g right
usemtl green
f 4 3 7 8
g top
usemtl gold
f 5 1 4 8
g left
usemtl orange
f 5 6 2 1
g bottom
usemtl purple
f 2 6 7 3
# 6 elements

示例引用了 master.mtl,我在任何地方都找不到。

因此,我从头开始写了一个 – master.mtl:

# Create as many materials as desired
# Each is referenced by name before the faces it applies to in the obj file

newmtl red
Ka 1.000000 0.000000 0.000000
Kd 1.000000 0.000000 0.000000
Ks 0.000000 0.000000 0.000000
Ns 0.000000

newmtl blue
Ka 0.000000 0.000000 1.000000
Kd 0.000000 0.000000 1.000000
Ks 0.000000 0.000000 0.000000
Ns 0.000000

newmtl green
Ka 0.000000 1.000000 0.000000
Kd 0.000000 1.000000 0.000000
Ks 0.000000 0.000000 0.000000
Ns 0.000000

newmtl gold
Ka 1.000000 1.000000 0.000000
Kd 1.000000 1.000000 0.000000
Ks 1.000000 1.000000 0.000000
Ns 0.000000

newmtl orange
Ka 1.000000 0.500000 0.000000
Kd 1.000000 0.500000 0.000000
Ks 0.000000 0.000000 0.000000
Ns 0.000000

newmtl purple
Ka 1.000000 0.000000 1.000000
Kd 1.000000 0.000000 1.000000
Ks 0.000000 0.000000 0.000000
Ns 0.000000

然后,我用我们的装载机试了一下,得到了这个:

然后,我修改了cube.obj以添加法线。

这是一个示例,其中双斜杠 (//) 出现在面索引中(由于缺少纹理坐标)。

带法线的文件 – cubeN.obj:

# This cube has a different material
# applied to each of its faces.
mtllib master.mtl
v 0.000000 2.000000 2.000000
v 0.000000 0.000000 2.000000
v 2.000000 0.000000 2.000000
v 2.000000 2.000000 2.000000
v 0.000000 2.000000 0.000000
v 0.000000 0.000000 0.000000
v 2.000000 0.000000 0.000000
v 2.000000 2.000000 0.000000
vn 0 0 1
vn 0 0 -1
vn 1 0 0
vn 0 1 0
vn -1 0 0
vn 0 -1 0
# 8 vertices
g front
usemtl red
f 1//1 2//1 3//1 4//1
g back
usemtl blue
f 8//2 7//2 6//2 5//2
g right
usemtl green
f 4//3 3//3 7//3 8//3
g top
usemtl gold
f 5//4 1//4 4//4 8//4
g left
usemtl orange
f 5//5 6//5 2//5 1//5
g bottom
usemtl purple
f 2//6 6//6 7//6 3//6
# 6 elements

除了样本没有完全损坏(在我们的加载程序中)之外,不确定这是否能证明任何事情。

必须承认,今天是我第一次使用 QtCreator 和 QML。

与 OP 相反,我在实验中使用了一个更简单的样本:

Qt 3D: Wireframe QML Example

经过一番折腾,我得到了如下回执:

  1. 在QtCreator中打开wireframe示例。
    该示例使用 Wavefront OBJ 文件 trefoil.obj.

  2. 在磁盘上找到 trefoil.obj
    我在.../Qt/Examples/Qt-5.13.0/qt3d/exampleresources/assets/obj.

  3. 下找到了
  4. 中的示例文件 cube.objcubeN.obj 存储到此文件夹中。
    无论如何,此示例中都没有引用 material 文件 master.mtl。 据我了解,materials 是在 QML 中定义的。 – 任何加载的 material 在任何情况下都会被覆盖。

  5. 在QtCreator的项目树视图中,将示例文件cube.objcubeN.obj添加到Resources/.../Qt/Examples/Qt-5.13.0/qt3d/exampleresources/obj.qrc/assets /obj.
    之后在文本编辑器中打开 .../Qt/Examples/Qt-5.13.0/qt3d/exampleresources/obj.qrc,我发现:

<RCC>
    <qresource prefix="/">
        <file>assets/obj/trefoil.obj</file>
        <file>assets/obj/toyplane.obj</file>
        <file>assets/obj/ball.obj</file>
        <file>assets/obj/plane-10x10.obj</file>
        <file>assets/obj/material-sphere.obj</file>
        <file>assets/obj/cube.obj</file>
        <file>assets/obj/cubeN.obj</file>
    </qresource>
</RCC>
  1. 我将文件 QML/TrefoilKnot.qml 复制到 QML/Cube.qmlQML/CubeN.qml 并替换了 source 条目分别 – Cube.qml:
import Qt3D.Core 2.0
import Qt3D.Render 2.0

Entity {
    id: root

    property real x: 0.0
    property real y: 0.0
    property real z: 0.0
    property real scale: 1.0
    property real theta: 0.0
    property real phi: 0.0
    property Material material

    components: [ transform, mesh, root.material ]

    Transform {
        id: transform
        translation: Qt.vector3d(root.x, root.y, root.z)
        rotation: fromEulerAngles(theta, phi, 0)
        scale: root.scale
    }

    Mesh {
        id: mesh
        source: "assets/obj/cube.obj"
    }
}
  1. 我将文件 Cube.qmlCubeN.qml 添加到 Resources/wireframe.qrc
  2. 我更改了 QML/main.qml 以添加实体 CubeCubeN:
    TrefoilKnot {
        id: trefoilKnot
        material: wireframeMaterial
    }
    Cube {
        id: cube
        material: wireframeMaterial
    }
    /* Excluded:
    CubeN {
        id: cubeN
        material: wireframeMaterial
    }*/

启动应用后,得到如下结果:

我对 CubeN 进行了同样的尝试,结果看起来很相似:

我在 Windows 10(64 位)上使用 Qt 5.13.0 和 Qt Creator 4.9.1。


关于objgeometryloader.cpp

根据我在资源中找到的内容,支持以下 OBJ 命令:

  • v定义顶点坐标
  • vn定义顶点法线
  • vt定义顶点纹理坐标
  • f 定义一个面(三角形或三角形扇形)
  • o 定义一个名称为对象。

此外,如果井号 # 出现在行首(没有缩进),则跳过空行和注释。

其他行,例如

  • mtllib 引用 material 文件
  • usemtl 从 material 文件中激活某个 material
  • g开团
  • s激活某个平滑组

似乎只是被忽略了。

考虑到这个插件是一个几何加载器,这似乎是合理的。


我在woboq上也看到了场景解析器的插件:

qt5/qt3d/src/plugins/sceneparsers/
+ assimp/
+ gltf/
+ gltfexport/

我用谷歌搜索了一下,但找不到任何与我当前的 Qt 版本 5.13 直接相关的内容,除了 Open Asset Import Library, version 4.1.0

我建议您使用 Qt 3D 模块中的 QMesh 来渲染复杂的 3D 文件。 Here 您可以找到有关如何将此 class 与 .stl 文件一起使用的示例,但是,如果您仔细阅读文档,您可以找到它使用 .obj 文件的部分.