1
$\begingroup$

This code creates a simple mesh (with two polygons instead of just one), but I am unable to find out how to give each vertex in the mesh a proper and precise place within the UV map. The idea is to create a quad polygon, give it a place within the UV map. Then when all the polygon faces are completed all vertices(within the exact same coordinates) get merged into one single mesh

Any ideas?

Thanx in advance! sorry if the question is too simple for this forum ...

## create mesh
import bpy

## CREATE MESH
verts = []
edges = []
faces = []

verts.append([
    0.0, # x
    10.0, # y
    0.0, # z
    ])
    
verts.append([
    10.0, # x
    0.0, # y
    0.0, # z
    ])
    
verts.append([
    0.0, # x
    0.0, # y
    10.0, # z
    ])
    
verts.append([
    -10.0, # x
    0.0, # y
    0.0, # z
    ])
    
edges.append([0,1])
edges.append([1,2])
edges.append([0,2])
edges.append([2,3])

faces.append([0,1,2])
faces.append([2,0,3])


##########
name = "New Object"
mesh = bpy.data.meshes.new(name)
obj = bpy.data.objects.new(name, mesh)
col = bpy.data.collections.get("Collection")
col.objects.link(obj)
bpy.context.view_layer.objects.active = obj
mesh.from_pydata(verts, edges, faces)
$\endgroup$
3
  • $\begingroup$ Just a small, friendly tip on code style: we all know the order of coordinates, no need for the # x, # y, # z comments. Also for simple values I would write them in one line. Then you can also instantiate entire verts list in one go, using space padding for readability. Also, using bmesh you don't need to specify edges - examples $\endgroup$ Sep 21 at 14:42
  • 1
    $\begingroup$ You don't need edges for from_pydata either (just pass [] for the edge list). $\endgroup$
    – scurest
    Sep 21 at 15:04
  • $\begingroup$ Thx for all the tips! $\endgroup$ Sep 23 at 6:31
1
$\begingroup$

You need one UV coordinate for every corner of a polygon. Fill in an array with your UVs with something like:

uvs = []

# Face 0
faces.append([0,1,2])
uvs += [
    0.0, 0.0,   # UV for first corner (vertex 0)
    1.0, 0.0,   # UV for second corner (vertex 1)
    1.0, 1.0,   # UV for third corner (vertex 2)
]

# Face 1
faces.append([2, 0, 3])
uvs += [
    0.0, 0.0,   # UV for first corner (vertex 2)
    1.0, 0.0,   # UV for second corner (vertex 0)
    1.0, 1.0,   # UV for third corner (vertex 3)
]

Then after from_pydata create the UVMap like this:

# Create a new UVMap
uv_layer = mesh.uv_layers.new(name="UVMap")

# Fill in your UVs
uv_layer.data.foreach_set("uv", uvs)
$\endgroup$
3
  • $\begingroup$ uv_layer.data.foreach_set("uv", uvs) It fails at the very last instruction, The array is only half of what it is supposed to be, so no UV map is created and I get an error; "Error: Array length mismatch (expected 24, got 12)" I have no idea why there is an array to match double the amount of vertices of what was given ... ? $\endgroup$ Sep 23 at 10:29
  • $\begingroup$ @Comic_Interlude I've tested this answer and it worked for me, I imagine Scurest also tested it. Perhaps you've modified your script incorrectly, for example perhaps you just pasted this answer's code to your script, and so you ended with twice as many faces? $\endgroup$ Sep 23 at 10:38
  • $\begingroup$ Okay, this code works perfectly, but I made the (very stupid) mistake not to check "edit mode" on, so the freshly made uv isn't visible then! which left me miffed for some time. $\endgroup$ Sep 24 at 8:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.