Here is something I recently used to count UV Islands as well as get some other info
import c4d
from collections import defaultdict
def get_uv_islands(obj, tol=1e-5):
"""
Compute UV islands for the given polygon object using its UVW tag.
This version retrieves the UV dictionary for each polygon using uvTag.GetSlow(polyIndex),
then groups connected polygons (sharing at least one UV coordinate) into islands
using an iterative flood-fill algorithm.
"""
uvw_tag = obj.GetTag(c4d.Tuvw)
if uvw_tag is None:
c4d.gui.MessageDialog("The object does not have a UVW tag.")
return None
poly_count = obj.GetPolygonCount()
# Build maps:
# - face_to_uvs: mapping from polygon index to its set of rounded UV keys.
# - uv_to_faces: reverse mapping from each UV key to the set of polygon indices using that UV.
face_to_uvs = defaultdict(set)
uv_to_faces = defaultdict(set)
def uv_key(vec):
# Round UV vector components to mitigate floating-point precision issues.
return (round(vec.x, 5), round(vec.y, 5))
# Build connectivity maps based on each polygon's UV data.
for poly_index in range(poly_count):
poly = obj.GetPolygon(poly_index)
uv_data = obj.GetTag(c4d.Tuvw).GetSlow(poly_index)
# If the polygon is a triangle, remove the extraneous 'd' key.
if poly.IsTriangle() and 'd' in uv_data:
del uv_data['d']
for key in uv_data:
uv_vec = uv_data[key]
key_tuple = uv_key(uv_vec)
face_to_uvs[poly_index].add(key_tuple)
uv_to_faces[key_tuple].add(poly_index)
# Use an iterative flood-fill to group connected faces.
islands = []
faces_left = set(range(poly_count))
while faces_left:
island = []
start_face = next(iter(faces_left)) # Pick an arbitrary face from unvisited ones.
stack = [start_face]
while stack:
face_idx = stack.pop()
if face_idx not in faces_left:
continue
faces_left.remove(face_idx)
island.append(face_idx)
# For every UV key in this face, add all neighboring faces.
for uv_val in face_to_uvs[face_idx]:
for neighbor in uv_to_faces[uv_val]:
if neighbor in faces_left:
stack.append(neighbor)
islands.append(island)
return islands
def get_island_uv_center(obj, uvw_tag, island):
"""
Given a polygon object, its UVW tag, and an island (list of polygon indices),
compute the UV bounding box and center.
"""
# Initialize min/max with infinities.
min_u = float('inf')
max_u = -float('inf')
min_v = float('inf')
max_v = -float('inf')
# Gather unique UV coordinates from all faces in the island.
unique_uvs = {}
for face_idx in island:
poly = obj.GetPolygon(face_idx)
uv_data = uvw_tag.GetSlow(face_idx)
if poly.IsTriangle() and 'd' in uv_data:
del uv_data['d']
for key in uv_data:
uv = uv_data[key]
key_tuple = (round(uv.x, 6), round(uv.y, 6))
unique_uvs[key_tuple] = uv
# Compute the bounding box.
for uv in unique_uvs.values():
if uv.x < min_u:
min_u = uv.x
if uv.x > max_u:
max_u = uv.x
if uv.y < min_v:
min_v = uv.y
if uv.y > max_v:
max_v = uv.y
center_u = (min_u + max_u) / 2.0
# Invert V axis so the center is correct in UV space.
center_v = 1.0 - ((min_v + max_v) / 2.0)
return center_u, center_v, min_u, max_u, min_v, max_v
def main():
doc = c4d.documents.GetActiveDocument()
obj = doc.GetActiveObject()
if obj is None:
c4d.gui.MessageDialog("Please select a polygon object.")
return
uvw_tag = obj.GetTag(c4d.Tuvw)
if uvw_tag is None:
c4d.gui.MessageDialog("The object does not have a UVW tag!")
return
islands = get_uv_islands(obj)
if islands is None:
return
num_islands = len(islands)
print("Number of UV islands:", num_islands)
for idx, island in enumerate(islands):
center_u, center_v, min_u, max_u, min_v, max_v = get_island_uv_center(obj, uvw_tag, island)
print("Island", idx, "has faces:", island)
print("Island Num",idx," Bounding Box: U [{:.6f}, {:.6f}], V [{:.6f}, {:.6f}]".format(min_u, max_u, min_v, max_v))
print(" Center: U = {:.6f}, V = {:.6f}".format(center_u, center_v))
if __name__=='__main__':
main()
Output looks something like
Number of UV islands: 2
Island 0 has faces: [0, 5, 3, 4]
Island Num 0 Bounding Box: U [0.004902, 0.495098], V [0.004902, 0.740196]
Center: U = 0.250000, V = 0.627451
Island 1 has faces: [1, 2]
Island Num 1 Bounding Box: U [0.004902, 0.495098], V [0.750000, 0.995098]
Center: U = 0.250000, V = 0.127451
Hope it is useful!