3
$\begingroup$

Blender 3.4.1 Windows 10

Here is a simple mesh in obj format

v -1.024831740629777332 -0.7316606105263611104 -1.11022302462515654e-16
v -1.174474239349365234 -0.7476682066917419434 -0.08013010025024414062
v 0.311189800500869751 -1.321910619735717773 -0.3170670270919799805
v 0.4356373862800485552 -1.130767581611495931 -5.551115123125782702e-17
v -0.7515343008920362111 0.3134878416699132253 0
v -0.8242673873901367188 0.5338582992553710938 -0.9901498556137084961
v -1.143023482091275467 -0.6993619864295770316 -1.387778780781445676e-17
v 0.7515343008920362111 -0.3134878416699132253 0
v 0.6294196029154086602 -0.6294196029154086602 0
v 0.6613966226577758789 -0.04038405418395996094 -1.227086782455444336
v -0.1114848981302206665 1.042185426809795867 0
v -0.4356373862800485552 1.130767581611495931 0
v -0.6294196029154086602 0.6294196029154086602 0
v 1.143023482091275467 0.6993619864295770316 0
f 2 3 4 1 
f 6 2 7 5 
f 6 3 2 
f 9 4 3 10 8 
f 10 6 12 11 
f 7 2 1 
f 13 12 6 5 
f 6 10 3 
f 10 14 8 
f 14 10 11 
f 12 13 9 8 14 11 
f 7 1 4 9 13 5 

It's getting imported correctly using obj importer, but when I'm creating a mesh using Python API and the above data, it's not working. Here is the code

faces = [(2, 3, 4, 1), (6, 2, 7, 5), (6, 3, 2), (9, 4, 3, 10, 8), (10, 6, 12, 11), (7, 2, 1), (13, 12, 6, 5), (6, 10, 3), (10, 14, 8), (14, 10, 11), (12, 13, 9, 8, 14, 11), (7, 1, 4, 9, 13, 5)]
verts = [(-1.0248317406297773, -0.7316606105263611, -1.1102230246251565e-16), (-1.1744742393493652, -0.7476682066917419, -0.08013010025024414), (0.31118980050086975, -1.3219106197357178, -0.31706702709198), (0.43563738628004856, -1.130767581611496, -5.551115123125783e-17), (-0.7515343008920362, 0.3134878416699132, 0.0), (-0.8242673873901367, 0.5338582992553711, -0.9901498556137085), (-1.1430234820912755, -0.699361986429577, -1.3877787807814457e-17), (0.7515343008920362, -0.3134878416699132, 0.0), (0.6294196029154087, -0.6294196029154087, 0.0), (0.6613966226577759, -0.04038405418395996, -1.2270867824554443), (-0.11148489813022067, 1.0421854268097959, 0.0), (-0.43563738628004856, 1.130767581611496, 0.0), (-0.6294196029154087, 0.6294196029154087, 0.0), (1.1430234820912755, 0.699361986429577, 0.0)]

name = "My_object"
mesh = bpy.data.meshes.new(name)

obj = bpy.data.objects.new(name, mesh)
bpy.data.collections['Collection'].objects.link(obj)
bpy.context.view_layer.objects.active = obj

mesh.from_pydata(verts, [], faces)
mesh.update(calc_edges=True)
mesh.validate(verbose=True)

It's showing lots of validation errors in the output console. How do I create a mesh identical to the obj importer?

$\endgroup$
1
  • $\begingroup$ How did you generate the values for the faces? They are incorrect. See my answer for the correct script. $\endgroup$ Apr 14, 2023 at 3:45

1 Answer 1

3
$\begingroup$

The face vertex order seems fine in your object text file but the face vertex order in your python script is incorrect. Here is the working script:

import bpy

faces = ((1, 2, 3, 0),
         (5, 1, 6, 4),
         (5, 2, 1),
         (8, 3, 2, 9, 7),
         (9, 5, 11, 10),
         (6, 1, 0),
         (12, 11, 5, 4),
         (5, 9, 2),
         (9, 13, 7),
         (13, 9, 10),
         (11, 12, 8, 7, 13, 10),
         (6, 0, 3, 8, 12, 4))

verts = ((-1.0248317406297773, -0.7316606105263611, -1.1102230246251565e-16), (-1.1744742393493652, -0.7476682066917419, -0.08013010025024414), (0.31118980050086975, -1.3219106197357178, -0.31706702709198), (0.43563738628004856, -1.130767581611496, -5.551115123125783e-17), (-0.7515343008920362, 0.3134878416699132, 0.0), (-0.8242673873901367, 0.5338582992553711, -0.9901498556137085), (-1.1430234820912755, -0.699361986429577, -1.3877787807814457e-17), (0.7515343008920362, -0.3134878416699132, 0.0), (0.6294196029154087, -0.6294196029154087, 0.0), (0.6613966226577759, -0.04038405418395996, -1.2270867824554443), (-0.11148489813022067, 1.0421854268097959, 0.0), (-0.43563738628004856, 1.130767581611496, 0.0), (-0.6294196029154087, 0.6294196029154087, 0.0), (1.1430234820912755, 0.699361986429577, 0.0))

name = "My_object"
mesh = bpy.data.meshes.new(name)

obj = bpy.data.objects.new(name, mesh)
bpy.data.collections['Collection'].objects.link(obj)
bpy.context.view_layer.objects.active = obj

mesh.from_pydata(verts, [], faces)
mesh.update(calc_edges=True)
mesh.validate(verbose=True)

In addition, you can easily generate the python script for recreating the mesh for any object using:

import bpy

#creates a script named `make-primitive-x.py` from the selected object

context = bpy.context
ob = context.object
if ob and ob.type == "MESH":
    mesh = ob.data
    me = ob.data
    txt = bpy.data.texts.new("make-primitive-x.py")

    faces = ",\n         ".join(f'{p.vertices[:]}' for p in me.polygons)     
    verts = ",\n         ".join(f"{v.co[:]}"  for v in me.vertices)

    txt.write(f"""

import bpy

context = bpy.context

verts = ({verts})

faces = ({faces})

me = bpy.data.meshes.new("{me.name}")
me.from_pydata(verts, [], faces)
ob = bpy.data.objects.new("{ob.name}", me)
context.collection.objects.link(ob)
context.view_layer.objects.active = ob
ob.select_set(True)
""")

This script creates a new text file with the equivalent python code for recreating the mesh of the selected object as shown below:

enter image description here

$\endgroup$
1
  • 1
    $\begingroup$ The text copied to .obj file seems to import fine with the same face vertex order. $\endgroup$ Apr 14, 2023 at 3:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .