9
$\begingroup$

I am new to blender and python and try to get the hang of it. PS: Everything should be achieved via python script.

I want to create a low poly model via ico-sphere. That's really easy because I just need to create a ico-sphere. Now I want to randomly select a face and one of his neighbours to merge them via bpy.ops.mesh.edge_face_add() to a new face.

I am having the following script:

bpy.ops.object.mode_set(mode = 'EDIT') # into edit mode
bpy.ops.mesh.select_all(action='DESELECT') # deselect everything
bpy.context.tool_settings.mesh_select_mode = (True , False , False) # only faces
mesh=bmesh.from_edit_mesh(me) # get mesh
mesh.faces.ensure_lookup_table() # update faces
mesh.faces[0].select = True # select face number 0
mesh.faces[1].select = True # select face number 1
bpy.ops.mesh.edge_face_add() # merge them
bpy.ops.mesh.select_all(action='DESELECT') # deselect everything

At first I am using bmesh which is experimental. I would like to use a blender api which isn't experimental. Any ideas? I tried it with faces[0] and 1 and it worked, they are neighbours. But I think that's not always. How can I find out which faces are next to faces[0] for example.

Thanks for helping!

$\endgroup$

1 Answer 1

14
$\begingroup$

does his help? Start with the template in:

  • TextEditor > Templates > Python > Bmesh Simple Editmode

import bpy
import bmesh

obj = bpy.context.edit_object
me = obj.data

bm = bmesh.from_edit_mesh(me)

face = bm.faces[3]
face.select = True
print(dir(face.verts[0].link_faces))
print(face.verts[0].link_faces[:])

# This gives the list of all edges that use that vertex.
# [<BMFace(0x7f7acb5ddb70), index=52, totverts=4>,    
#  <BMFace(0x7f7acb5ddbe0), index=54, totverts=4>,
#  <BMFace(0x7f7acb5ddba8), index=53, totverts=4>,  
#  <BMFace(0x7f7acb5dd0b8), index=3, totverts=4>]

bmesh.update_edit_mesh(me, True)

There's also link_edges which could also prove useful, arguably more so

import bpy
import bmesh

obj = bpy.context.edit_object
me = obj.data

bm = bmesh.from_edit_mesh(me)

# just assume now there is only one selected face
selected_face = [f for f in bm.faces if f.select][0]

for edge in selected_face.edges:
    linked = edge.link_faces
    for face in linked:
        face.select = True

bmesh.update_edit_mesh(me, True)

produces

enter image description here enter image description here

And finally, the join command

import bpy
import bmesh

obj = bpy.context.edit_object
me = obj.data

bm = bmesh.from_edit_mesh(me)

# just assume now there are at least 2 selected, and are touching
selected_faces = [f for f in bm.faces if f.select]

# the script equivalent of the F key        
bmesh.ops.contextual_create(bm, geom=selected_faces)

bmesh.update_edit_mesh(me, True)

enter image description here

Regarding your statement about Bmesh being experimental, I wouldn't worry about that too much, it's being used a lot and has proven to be more than capable. The Bmesh.ops docs are an excellent but admittedly terse resource:

$\endgroup$
9
  • $\begingroup$ Wow, Thanks! That helped a lot! :) One thing I am a bit puzzled is the bmesh.ops.contextual_create(bm, geom=selected_faces), which is equivalent to bpy.ops.mesh.edge_face_add(). Why are there two methods which are doing the same? What is more correct? contextual_create or edge_face_add()? $\endgroup$
    – Hamburml
    Apr 25, 2015 at 13:28
  • $\begingroup$ bpy.ops.* and bmesh.ops.* are different routes to operate on meshes. The two functions you mention may be in some way equivalent, but if you have a reference to a bmesh, then you don't use bpy.ops. Think of bmesh as a virtual Mesh until you call update_edit_mesh on it. Whereas bpy.ops.* requires the mesh directly. I've probably not explained that very well... sorry. $\endgroup$
    – zeffii
    Apr 25, 2015 at 13:38
  • $\begingroup$ Naaah, you don't need to apologize. Thanks for helping! I will try it right now :-) $\endgroup$
    – Hamburml
    Apr 25, 2015 at 13:44
  • $\begingroup$ Thank you! It's working but I need to call mesh.faces.ensure_lookup_table(). I think it is because I create the object a few lines above in my script. $\endgroup$
    – Hamburml
    Apr 25, 2015 at 13:56
  • $\begingroup$ yeah, i didn't want to potentially complicate a simple example. $\endgroup$
    – zeffii
    Apr 25, 2015 at 14:37

You must log in to answer this question.

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