I have a model in .glb format with nothing edit(but a mesh) in the scene. How do I apply a material of a glb/gltf mesh using Python? I am using Pygltflib and Trimesh although I can use other libraries.
Asked
Active
Viewed 1,238 times
0
-
Do you currently have a primitive / mesh in the gltf? – frankenapps Feb 10 '21 at 08:01
-
yes I do have a mesh. – Steve Scott Feb 11 '21 at 05:24
1 Answers
1
I can only give a genereal answer, because you did not provide any code, but you would do it like this in principal:
material = Material() # Create a material
pbr = PbrMetallicRoughness() # Use PbrMetallicRoughness
pbr.baseColorFactor = [1.0, 0.0, 0.0, 1.0] # solid red
material.pbrMetallicRoughness = pbr
after that supply the material to your primitive like that
primitive.material = 0
and do not forget to add it to the gltf. As always if you use more materials, the order will be important of course:
gltf.materials.append(material)
For completeness here is how to add a double sided red metallicRoughnessMaterial with "MASK" alphaMode to the triangle example and save it as .glb:
from pygltflib import *
# create gltf objects for a scene with a primitive triangle with indexed geometry
gltf = GLTF2()
scene = Scene()
mesh = Mesh()
material = Material()
primitive = Primitive()
node = Node()
buffer = Buffer()
bufferView1 = BufferView()
bufferView2 = BufferView()
accessor1 = Accessor()
accessor2 = Accessor()
# add data
buffer.uri = "data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAA="
buffer.byteLength = 44
bufferView1.buffer = 0
bufferView1.byteOffset = 0
bufferView1.byteLength = 6
bufferView1.target = ELEMENT_ARRAY_BUFFER
bufferView2.buffer = 0
bufferView2.byteOffset = 8
bufferView2.byteLength = 36
bufferView2.target = ARRAY_BUFFER
accessor1.bufferView = 0
accessor1.byteOffset = 0
accessor1.componentType = UNSIGNED_SHORT
accessor1.count = 3
accessor1.type = SCALAR
accessor1.max = [2]
accessor1.min = [0]
accessor2.bufferView = 1
accessor2.byteOffset = 0
accessor2.componentType = FLOAT
accessor2.count = 3
accessor2.type = VEC3
accessor2.max = [1.0, 1.0, 0.0]
accessor2.min = [0.0, 0.0, 0.0]
pbr = PbrMetallicRoughness() # Use PbrMetallicRoughness
pbr.baseColorFactor = [1.0, 0.0, 0.0, 1.0] # solid red
material.pbrMetallicRoughness = pbr
material.doubleSided = True # make material double sided
material.alphaMode = MASK # to get around 'MATERIAL_ALPHA_CUTOFF_INVALID_MODE' warning
primitive.attributes.POSITION = 1
primitive.material = 0
node.mesh = 0
scene.nodes = [0]
# assemble into a gltf structure
gltf.scenes.append(scene)
gltf.meshes.append(mesh)
gltf.materials.append(material)
gltf.meshes[0].primitives.append(primitive)
gltf.nodes.append(node)
gltf.buffers.append(buffer)
gltf.bufferViews.append(bufferView1)
gltf.bufferViews.append(bufferView2)
gltf.accessors.append(accessor1)
gltf.accessors.append(accessor2)
gltf.convert_buffers(BufferFormat.BINARYBLOB) # Convert buffers to allow saving as .glb
# save to a .glb file
gltf.save("triangle.glb")

frankenapps
- 5,800
- 6
- 28
- 69
-
How do I load an STL into pygltflib? I am trying ```mesh = GLTF2().load(my_path)``` I am getting the error ```UnicodeDecodeError: 'charmap' codec can't decode byte 0x90 in position 747: character maps to
``` I think this load method expects a valid gltf. – Steve Scott Feb 23 '21 at 21:13 -
I don’t think you are able to load a .stl like that. Why would you expect this to work? It’s a totally different format. – frankenapps Feb 24 '21 at 05:55
-
You should be able to read the .stl with something like that http://python-stl.readthedocs.io/en/latest/reading.html and then create the primitives and vertecies accordingly. Feel free to open another question if you need more guidance on that. – frankenapps Feb 24 '21 at 06:01
-
My question is posted here: https://stackoverflow.com/questions/66341118/how-do-i-import-an-stl-into-pygltflib – Steve Scott Feb 24 '21 at 18:44