MAX
MAX

Reputation: 23

Texture (QTexture2D) from image file applied to Qt3D mesh appears as plain gray - Python

I am trying to apply a texture from a jpg file to a mesh (.obj file). Both files originate from a 3D scanner and can be open in 3D tools, showing correctly.

How can I get a Qt3D mesh object to properly show in a viewer with a texture which originates from a file?

I create a mesh and load the data from the .obj file. I create a texture object and load the data from the .jpg file. I then create a material object and associate the texture to it. The object then shows as plain gray in the visualizer. Here is the code snippet. I also set a QPointLight (code below).

# Root entity.
self.rootEntity = QEntity()

# obj
filepath1 = "some_3D_file.obj"
texture_filepath1 = "some_image_file.jpg"

mesh_entity = QEntity(self.rootEntity)
mesh_object = Qt3DRender.QMesh()
mesh_object.setSource(QtCore.QUrl.fromLocalFile(filepath1))
mesh_entity.addComponent(mesh_object)

# Create texture
mesh_texture_image = Qt3DRender.QTextureImage(self.rootEntity)
mesh_texture_image.setSource(QtCore.QUrl.fromLocalFile(texture_filepath1))
mesh_texture_2D = Qt3DRender.QTexture2D(self.rootEntity)
mesh_texture_2D.addTextureImage(mesh_texture_image)

# Create material
mesh_material = QDiffuseSpecularMaterial(self.rootEntity)
mesh_material.setNormal(mesh_texture_2D)
mesh_material.setDiffuse(QColor(255, 255, 255, 0))
mesh_material.setSpecular(QColor(55, 55, 55, 0))

mesh_entity.addComponent(mesh_material)

Here is the code for the light source:

        # Light
        light_entity = QEntity(self.rootEntity)
        light = Qt3DRender.QPointLight(light_entity)
        light.setConstantAttenuation(0)
        light_entity.addComponent(light)
        light_transform = QTransform()
        light_transform.setTranslation(QVector3D(0, 100, 200))
        light_entity.addComponent(light_transform)

I tried various combinations of setting normal, diffuse, and specular, with either the loaded texture and/or plain QColor values with no luck of showing the texture image. It seems setNormal does not do much whatever I do with it. Attributing a Qcolor to setDiffuse results in the object showing the corresponding color in the viewer (as expected).

As a side question, why is there so few results when I search for Qt3D information/issues/code exmaples? I would have expected a large community using the module. Is everyone using some other 3D renderer/visualizer module that I am not aware of?

Thanks for your help.

Upvotes: 1

Views: 101

Answers (2)

MAX
MAX

Reputation: 23

I found that using QTextureMaterial worked in viewing the texture on the mesh (and it worked even without any light source)

mesh_material = QTextureMaterial(self.rootEntity)
mesh_material.setTexture(mesh_texture_2D)

However, I struggled with the fact that areas of the mesh which don't have a texture (the texture is purposely smaller than the mesh it maps to) cannot be viewed (either it is white on white, or just does not show at all). I tried adding a second material (plain color) to the entity, with no success. I am sure there is a way to have two overlapping/layered textures or materials such that one is a "base" texture having plain color, with the actual image texture over it, but have not been successful in finding how to do that.

Upvotes: 1

karlphillip
karlphillip

Reputation: 93468

I think the confusion comes from the type of texture that you have and how to use it with the right Qt3D material.

I'm going to assume that your texture has colors in it and it doesn't really represent a normal map. If that's the case, then you need to use a QDiffuseMapMaterial instead:

mesh_material = QDiffuseMapMaterial(self.rootEntity)
mesh_material.setDiffuse(mesh_texture_2D)
mesh_material.setAmbient(QColor(55, 55, 55, 0))

And make sure to add a light source to the scene!

Upvotes: 1

Related Questions