Hi,
I’m struggling with this for a while and I can’t get what’s wrong
So… What I’m trying to do:
1.Get face’s UV
2.Scan canvas to check if every texture’s pixel is white
3.If is not then do not select face.
I done some research and found a few things then I customized it for my purposes, so now
I’m able to get correct canvas pixels (canvas of face’s UV) to look up for black color but then magic happens and I get results like in the pictures below
Do you have any tips, thanks for any help.

And here blend file
select_pixel_by_face_colour.blend (2.3 MB)
import bpy
import math
from math import floor, ceil
from mathutils import Vector
from mathutils.interpolate import poly_3d_calc
from bpy.types import Scene, Mesh, MeshPolygon, Image
#Used when uv coordinate <1 or >1
def emod(n, m):
return ((n % m) + m) % m;
#returns ceil(face's top left corner texture's pixel coords) and ceil(face's bottom right corner texture's pixel coords)
def canvasLookup(img,tl,br):
#print(tl,br)
#print(emod(tl[0], 1))
tx1 = (min(emod(tl[0], 1) * img.size[0] , img.size[0]))
ty1 = (min(emod(tl[1], 1) * img.size[0], img.size[0]))
tx2 = (min(emod(br[0], 1) * img.size[0] , img.size[0]))
ty2 = (min(emod(br[1], 1) * img.size[0], img.size[0]))
tx1 = int(floor(tx1))
tx2 = int(ceil(tx2))
ty1 = int(ceil(ty1))
ty2 = int(floor(ty2))
return(tx1,ty1,tx2,ty2)
#Searches u or v line of texture's pixels to find if
#it has intersection with rgb != (1,1,1) then return false
def sideLookup(uv_pixels,i,x1,x2):
select = False
for j in range(min(x1,x2),max(x1,x2)+1):
a,b,c = (uv_pixels[i*j*4+0],uv_pixels[i*j*4+1],uv_pixels[i*j*4+2])
#print(a,b,c)
if(a != 1 and b != 1 and c != 1):
select = False
break
else:
select = True
break
return select
#Searches canvas of face - if it has brack intersection
#if any side of pixels has then return(DO NOT SELECT FACE)
def getSelect(img, x1,y1,x2,y2):
uv_pixels = img.pixels # Accessing pixels directly is quite slow. Copy to new array and pass as an argument for massive performance-gain if you plan to run this function many times on the same image (img.pixels[:]).
select = sideLookup(uv_pixels,max(y1,y2),x1,x2) #top line of pixels
if(select != True):
return(False)
select2 = sideLookup(uv_pixels,min(y1,y2),x1,x2) #bottom line of pixels
if(select != True):
return(False)
select3 = sideLookup(uv_pixels,min(x1,x2)+1,y1,y2-1) #left line of pixels w/o first and last from top line
if(select != True):
return(False)
select4 = sideLookup(uv_pixels,max(x1,x2)+1,y1,y2-1) #right line of pixels w/o first and last from bottom line
if(select != True):
return(False)
return(True)
def pixelColor_select(polyCount,img):
img_size = 256
obj = bpy.context.object
mesh = obj.data
point = bpy.context.scene.cursor.location
face_idx = obj.closest_point_on_mesh(point)[-1]
ob = bpy.context.active_object
face_tl_br = []
face_index = 0
#this loop is that I got from forum somwhere
for face in ob.data.polygons:
if(face_index == polyCount):
break
for vert_idx, loop_idx in zip(face.vertices, face.loop_indices):
uv_coords = ob.data.uv_layers.active.data[loop_idx].uv
#print("face idx: %i, vert idx: %i, uvs: %f, %f" % (face.index, vert_idx, uv_coords.x, uv_coords.y))
face_tl_br.append((uv_coords.x, uv_coords.y))
#here you can see that it picks up vertexes clock-wise
#starting with bottom-left vertex of face
#for i in range(0,4):
#print(face_tl_br[i][0]*100,face_tl_br[i][1]*100)
a,b,c,d = canvasLookup(img,face_tl_br[1],face_tl_br[3]) #as above - take top left and bottom right pos of vert
if(a==256):
a=1;
if(b==256):
b=1;
if(c==256):
c=1;
if(d==256):
d=1;
#print(a,b,c,d)
#here I assume that I'm in (U>0,V>0) quarter
boo = getSelect(img,a,b,c,d)
# min(b,d)%256,max(b,d)%256,min(a,c)%256,max(a,c)%256)
face.select = boo
print(face_index)
face_index+=1
face_tl_br = []
polyCount = 20000
img = bpy.data.images.get("cegly256_depth.png")
pixelColor_select(polyCount,img)
print("DONE")