2
$\begingroup$

How to select the vertical edges, using python code if a selected previously the cube?

Vertical edges

$\endgroup$

2 Answers 2

3
$\begingroup$

You can use this script to select each edge if its two vertices' X and Y coordinate are both really close to each other.

import bpy
import bmesh

obj = bpy.context.active_object  # Get selected object

epsilon = 1e-5  # Threshold to account for floating point precision

if obj:
    bpy.ops.object.mode_set(mode='EDIT')  # Go into edit mode
    bpy.ops.mesh.select_mode(type="EDGE")  # Switch to edge select mode

    bm = bmesh.from_edit_mesh(obj.data)  # Create bmesh object for easy mesh evaluation

    for e in bm.edges:  # Check all edges
        first_pos = e.verts[0].co  # Get first vert position of this edge
        other_pos = e.verts[1].co  # Get second vert position of this edge

        # Select or deselect depending of the relative position of both vertices
        e.select_set(abs(first_pos.x - other_pos.x) <= epsilon and abs(first_pos.y - other_pos.y) <= epsilon)
        
    bmesh.update_edit_mesh(obj.data)  # Update the mesh in edit mode

enter image description here

How to run a script

$\endgroup$
2
  • $\begingroup$ how you recorded the video? $\endgroup$
    – user77647
    Jun 12, 2020 at 12:22
  • $\begingroup$ I used the software ScreenToGif $\endgroup$
    – Gorgious
    Jun 12, 2020 at 13:16
2
$\begingroup$

The dot product

If two vectors are parallel then the dot product of their normalized direction will be 1 if in same direction (angle between 0) or -1 in opposite direction -1 (angle between 180 degrees)

Checking that the absolute value of dot product is around 1 will find edges defined by the vertex coordinate difference regardless of order.

Have used this method in example here Subdividing cubes at different intervals

So similarly

    def aligned(e, axis, TOL=1e-5):
        axis = Vector(axis).normalized()
        dir = (e.verts[1].co - e.verts[0].co).normalized()
        return (1 - abs(dir.dot(axis))) < TOL

    # select if aligned with local z axis.
    for e in bm.edges:
        e.select_set(aligned(e, (0, 0, 1)) 

    # select if aligned with global z axis
    axis = ob.matrix_world.inverted() @ Vector((0, 0, 1)) # local space
    for e in bm.edges:
        e.select_set(aligned(e, axis)) 

(if doubles in mesh will need to deal with zero length edges.)

Hardcode for default cube.

if this is a freshly added default cube can rely on the edges having the same index each time, and could select based on index.

geom=[e.index for e in bm.edges if aligned(e, (0, 0, 1))]
print(geom)

Outputs [1, 3, 6, 9] so the bmesh edges of the default cube in $Z$ dir are

bm.edges.ensure_lookup_table()
vertical_edges = [bm.edges[i] for i in (1, 3, 6, 9)]
$\endgroup$
1
  • $\begingroup$ How rather than selecing every edge in the shape how can you select just one edge any edge? $\endgroup$
    – ofey
    Apr 23, 2022 at 21:34

You must log in to answer this question.