Using python to scale/resize a selected groups of faces with individual origin

question based on this topic Using python and bmesh to scale/resize a face in place where each face was scaled separately.

So actually the question in the title. I'm newbie to python. I tried to find connected faces based on the same vertex indexes, then calculate the average mean of the vertices positions included this faces(like a origin point). But it works only for single group faces, how to make it for multiple group faces?  import bpy
import bmesh
import numpy as np
from mathutils import Vector as vec

#EDIT mode#
me = bpy.context.edit_object.data
bm = bmesh.from_edit_mesh(me)
scale_factor = 0.5

seleted_vert_group = []
verts_co_x = []
verts_co_y = []
verts_co_z = []

#checking for matches
for face1 in bm.select_history:
passwither = 0 #pass double matched face
for face2 in bm.select_history:
if face1 == face2:
continue
for vert1 in face1.verts:
for vert2 in face2.verts:
if passwither == 1:
continue
if vert1.index == vert2.index:
passwither = 1
print(f'face index: {face1.index}')
for vert in face1.verts:
seleted_vert_group.append(vert)
verts_co_x.append(vert.co.x)
verts_co_y.append(vert.co.y)
verts_co_z.append(vert.co.z)

co_x = np.sum(verts_co_x)/len(verts_co_x)
co_y = np.sum(verts_co_y)/len(verts_co_y)
co_z = np.sum(verts_co_z)/len(verts_co_z)
origin_point = vec((co_x,co_y,co_z))

for vert in set(seleted_vert_group):
vert.co = origin_point + scale_factor * (vert.co - origin_point)

bmesh.update_edit_mesh(me)

Find connected islands • Tag all selected faces as false
• Pop one selected face tag as true
• Yield recursively to find all selected and connected faces (an island)
• Scale the verts of the island based on average vert loc. (Could use face centers instead)
• Remove the island from selected set

See image on how this may not work as expected for faces touching at vertex corners.

import bpy
import bmesh
from mathutils import Vector, Matrix

#EDIT mode#
me = bpy.context.edit_object.data
bm = bmesh.from_edit_mesh(me)
scale_factor = 0.5

faces = set(f for f in bm.faces if f.select)

def walk_island(face):
face.tag = True
yield face
faces = [f for e in face.edges for f in e.link_faces if not f.tag and f.select]
for f in faces:
yield from walk_island(f)

def scale(island):
verts = set(v for f in island for v in f.verts)
bmesh.ops.scale(
bm,
verts=list(verts),
vec=(scale_factor,) * 3,
space=Matrix.Translation(
sum((-v.co for v in verts), Vector()) / len(verts)
))

for f in faces:
f.tag = False

while faces:
f = faces.pop()
island = set(walk_island(f))
scale(island)
faces -= island

bmesh.update_edit_mesh(me)

Hi you should move back them into first position.

I answered based on this question import bpy
import bmesh

context = bpy.context

ob = context.edit_object
me = ob.data
bm = bmesh.from_edit_mesh(me)
scale_factor = 0.5

for face in bm.select_history:
center = face.calc_center_median()
for v in face.verts:
v.co = center + scale_factor * (v.co - center)

bmesh.update_edit_mesh(me)
• The problem this method is that the connected edges will have a double scale
– day9
Sep 4 '20 at 19:57