5
$\begingroup$

I essentially want to put a fence up around the edge of my object, is there a way I can select all vertices with 3 edges connected to it?

enter image description here

for vertex in object:
    if vertex.connectededges == 3:
        select
$\endgroup$

3 Answers 3

5
$\begingroup$

In your example, the 4 corners wouldn't get selected because they are connected to 2 edges.

However there is a handy operator with SHIFT + G or Select>Select Similar then "Amount of connecting edges"

enter image description here

Alternatively, if used in a script, you can use the operator :

bpy.ops.mesh.select_similar(type='EDGE', threshold=0.01)

But you need to first select some vertices.

enter image description here

If you can't select the vertices before running your script, use this :

import bpy
import bmesh

mesh = bpy.context.object.data  # Get selected object's mesh

bm = bmesh.from_edit_mesh(mesh) 
# Create new edit mode bmesh to easily acces mesh data


for v in bm.verts:
    v.select_set(len(v.link_edges) in (2,3))
# Select all vertices that have 2 or 3 links and deselect the others

bmesh.update_edit_mesh(mesh)  # Transfer the data back to the object's mesh

Source and Source 2

$\endgroup$
4
  • $\begingroup$ Would be wary of the method used in copied bmesh script. If there are changes to mesh in edit mode could be trashed, since it is loading the bmesh then toggling out of edit mode, writing to mesh with selection, then toggling into edit mode. Would either use an edit mode bmesh, or load the mesh after toggling into object object. Confirmed..Simple test: Default cube > edit mode > move some verts, > run script > back to default cube. $\endgroup$
    – batFINGER
    Apr 9, 2020 at 13:16
  • $\begingroup$ @batFINGER I understand, honest mistake due to my inexperience ! Would you be willing to edit the answer to provide a more suitable method since I don't (yet) know the difference between edit mode bmesh and object mode bmesh ? (even if your answer is obviously the simplest one) $\endgroup$
    – Gorgious
    Apr 9, 2020 at 13:23
  • $\begingroup$ Not sure re simplest, one that selects boundaries. If the grid was poked for example, still selects boundaries. Would simply use an edit mode bmesh. Wonder about the ob.select_set if it is to become default and setting via v.select = True is going to be phased out. Accidentally reverted to old ways in my answer lol. $\endgroup$
    – batFINGER
    Apr 9, 2020 at 13:28
  • $\begingroup$ Okay I got it from your answer, it's shorter and less error-prone as you said. In other languages direct attribute access is a bit frowned upon so I guess the setter usage is more encouraged ? $\endgroup$
    – Gorgious
    Apr 9, 2020 at 13:45
6
$\begingroup$

Boundary edges

I essentially want to put a fence up around the edge of my object

IMO Simplest here to select edges that are boundaries, ie are connected to only one face.

import bpy
import bmesh

ob = bpy.context.edit_object

me = ob.data
bm = bmesh.from_edit_mesh(me)

for e in bm.edges:
    e.select = e.is_boundary

bmesh.update_edit_mesh(me)

The vertex selection is implied by the edges. .. which is why I could have used

e.select_set(e.is_boundary)

BMEdge.select_set(select):

Set the selection. This is different from the select attribute because it updates the selection state of associated geometry.

Although in this case I'm of the belief that the verts of an edge are selected with the edge. So

verts = set(v for e in boundary_edges for v in e.verts)

will be same as selected verts.

v for v in bm.verts if v.select

Using the bmesh to extrude those edges.

Rather than selecting the edges, can instead feed them directly into bmesh operators. For the example below the vertices created as a result of extruding boundary edges are fed into transform operator, and moved up one in Z.

enter image description here Result on 10 x 10 default grid

Notice newly created geometry added with bmesh is unselected by default. Run both these scripts below in edit mode.

import bpy
import bmesh
from bmesh.types import BMVert
from mathutils import Matrix

ob = bpy.context.edit_object

me = ob.data
bm = bmesh.from_edit_mesh(me)
bmesh.ops.transform(
    bm,
    verts = [
            e for e in 
                bmesh.ops.extrude_edge_only(
                    bm,
                    edges=[e for e in bm.edges if e.is_boundary],
            )["geom"] 
            if isinstance(e, BMVert)
            ],
    matrix=Matrix.Translation((0, 0, 1)),
    )

bmesh.update_edit_mesh(me)
$\endgroup$
2
$\begingroup$

Sure you can.

  1. Select one vertex with 3 connected edges
  2. Go to Select > Similar > Amount of connecting edges
  3. Done.

enter image description here

$\endgroup$

You must log in to answer this question.

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