# How to select vertices and add them to Vertex Group?

I have this sail. I have coordinates of all 4 points.

I need to add all 4 vertices (1-4) and all vertices between 4 and 3 points via python to a Vertex Group called 'SailPin'.

At the moment I have this script which in EDIT mode can select 4 points for me only:

import bpy
import bmesh
import math
from mathutils import Vector, kdtree

s1 = bpy.data.objects['sail1.007'].matrix_world.translation
s2 = bpy.data.objects['sail2.007'].matrix_world.translation
s3 = bpy.data.objects['sail3.007'].matrix_world.translation
s4 = bpy.data.objects['sail4.004'].matrix_world.translation

coords_to_find = [s1, s2, s3, s4]

# Get the active mesh
obj = bpy.context.edit_object
me = obj.data
bm = bmesh.from_edit_mesh(me)

size = len(bm.verts)
kd = kdtree.KDTree(size)

for i, vtx in enumerate(bm.verts):
kd.insert(vtx.co, i)
kd.balance()

for idx, vtx in enumerate(coords_to_find):
co, index, dist = kd.find(vtx)  # dist is the distance
print(idx, vtx, index, co)
bm.verts[index].select = True

# Show the updates in the viewport
# and recalculate n-gon tessellation.
bmesh.update_edit_mesh(me, True)

How to do so?

You have two problems to solve. Adding the vertices to the vertex group is easy enough. You simply execute

for each vertex you want in the group, having set vertex_group to the group you want to add vertices to.

The hard part is finding the vertices that lie between vertex 3 and vertex 4 in your diagram. This code is full of explanatory comments, but it is very fragile -- with all of the assumptions spelled out. There are probably better ways to do this that remove some of the assumptions, but at least this works.

import bpy
import bmesh

# Assumes the sail is the selected object
# Assumes the sail is a trapazoid
# Assumes the sail is a parallel to the XY Plane
# Assumes the sail top and bottom edges are parallel to the X Axis

object = bpy.context.active_object
mesh = object.data

saved_mode = bpy.context.mode
if not saved_mode == 'EDIT_MESH':
bpy.ops.object.mode_set(mode='EDIT')

bm = bmesh.from_edit_mesh(mesh)
bm.verts.ensure_lookup_table()
bm.edges.ensure_lookup_table()

# The corners are vertices that are on the
# boundary and only have two edges.
# interior vertices will have 4 edges.
# non-corner boundary vertices will have 3 edges.
# Find the corners, and while you're at it,
# the Z coordinate of the top and bottom.
corners = set()
zmin = 10000
zmax = -10000
for vert in bm.verts:
if vert.is_boundary and len(vert.link_edges) == 2:
if zmin > vert.co.z:
zmin = vert.co.z
if zmax < vert.co.z:
zmax = vert.co.z

# To figure out the vertices that lie between the
# top corners, we need to know which of the four
# corners are the top corners.
# rely on the top and bottom edges being
# parallel to the X axis
top_corners = []
for vert in corners:
if vert.co.z == zmax:
top_corners.append(vert)

# Next we have to pick a corner and determine
# which edge is parallel to X.  We again
# rely on the edge being parallel to X
vert = top_corners[0]
v2 = e.other_vert(vert)
if not v2.co.z == vert.co.z:

top_spar = [v2]

# For each vertex on the top edge, find the
# other vertex on the edge.
# Repeat the search until we reach the other corner.
while v2.index != top_corners[1].index:
if e.is_boundary and not e.other_vert(v2) == vert:
vert = v2
v2 = e.other_vert(v2)
top_spar.append(v2)
break

# Convert the vertices to their indices since the bmesh
pin_list = set()
for vert in corners:

for vert in top_spar:

bmesh.update_edit_mesh(mesh)
if not saved_mode == 'EDIT_MESH':
bpy.ops.object.mode_set(mode=saved_mode)

# This only works if the mesh is not in edit mode.
# Create the vertex group.  This assumes it doesn't
$$`$$