def compute_normals_hash(sc): out = [] triangle_normals = len(sc.faces) * [[.0, .0, .0]] def hash(p): return .11234 * p[0] + .35678 * p[1] + .67257 * p[2] from collections import defaultdict pt_table = defaultdict(list) for i, t in enumerate(sc.faces): p1 = sc.points[t[0]] p2 = sc.points[t[1]] p3 = sc.points[t[2]] pt_table[hash(p1)].append((i, p1, t[0])) pt_table[hash(p2)].append((i, p2, t[1])) pt_table[hash(p3)].append((i, p3, t[2])) normal = vcross(sub(p2, p1), sub(p3, p1)) normal = vnorm(normal) triangle_normals[i] = normal i = 0 normals = [] faces_normals = [] for t in sc.faces: p1 = sc.points[t[0]] p2 = sc.points[t[1]] p3 = sc.points[t[2]] for point in [p1, p2, p3]: # we assume no collisions in the hash value = pt_table[hash(point)] point_index = value[0][2] first_point = value[0][1] # compute the normal of each triangles around # TODO should be done just once for each triangle in pre-process neighbors_normals = [] for t_index, p, _ in value: assert p == first_point neighbors_normals.append(triangle_normals[t_index]) N = (sum(n[0] for n in neighbors_normals) / len(neighbors_normals), sum(n[1] for n in neighbors_normals) / len(neighbors_normals), sum(n[2] for n in neighbors_normals) / len(neighbors_normals)) # normalize normal N = vnorm(N) # print N normals.append(N) faces_normals.append((3 * i, 3 * i + 1, 3 * i + 2)) i += 1 return normals, faces_normals
def compute_normals_fast(sc): out = [] triangle_normals = range(len(sc.faces)) vert_faces = [[] for _ in sc.points] for i, t in enumerate(sc.faces): # Compute face normal p1 = sc.points[t[0]] p2 = sc.points[t[1]] p3 = sc.points[t[2]] normal = vcross(sub(p2, p1), sub(p3, p1)) normal = vnorm(normal) triangle_normals[i] = normal # add triangles in point/triangle table vert_faces[t[0]].append(i) vert_faces[t[1]].append(i) vert_faces[t[2]].append(i) i = 0 normals = [] faces_normals = [] for t in sc.faces: for fv in t: X, Y, Z = 0, 0, 0 for incident_face in vert_faces[fv]: x, y, z = triangle_normals[incident_face] X += x Y += y Z += z cnt = len(vert_faces[fv]) N = (X / cnt, Y / cnt, Z / cnt) # normalize normal N = vnorm(N) # print N normals.append(N) faces_normals.append((3 * i, 3 * i + 1, 3 * i + 2)) i += 1 return normals, faces_normals
def compute_normals(sc): out = len(sc.points) * [ [.0, .0, .0] ] triangle_normals = len(sc.faces) * [ [.0, .0, .0] ] def hash(p): return .11234 * p[0] + .35678 * p[1] + .67257 * p[2] from collections import defaultdict pt_table = defaultdict(list) for i, t in enumerate(sc.faces): p1 = sc.points[t[0]] p2 = sc.points[t[1]] p3 = sc.points[t[2]] pt_table[hash(p1)].append( (i, p1, t[0]) ) pt_table[hash(p2)].append( (i, p2, t[1]) ) pt_table[hash(p3)].append( (i, p3, t[2]) ) normal = vcross(sub(p2, p1), sub(p3, p1)) normal = vnorm(normal) triangle_normals[i] = normal for key, value in pt_table.iteritems(): # we assume no collisions in the hash point_index = value[0][2] first_point = value[0][1] # compute the normal of each triangles around # TODO should be done just once for each triangle in pre-process normals = [] for t_index, p, _ in value: assert p == first_point normals.append(triangle_normals[t_index]) N = ( sum(n[0] for n in normals) / len(normals), sum(n[1] for n in normals) / len(normals), sum(n[2] for n in normals) / len(normals) ) # print N out[point_index] = N return out
def compute_normals(sc): out = len(sc.points) * [[.0, .0, .0]] triangle_normals = len(sc.faces) * [[.0, .0, .0]] def hash(p): return .11234 * p[0] + .35678 * p[1] + .67257 * p[2] from collections import defaultdict pt_table = defaultdict(list) for i, t in enumerate(sc.faces): p1 = sc.points[t[0]] p2 = sc.points[t[1]] p3 = sc.points[t[2]] pt_table[hash(p1)].append((i, p1, t[0])) pt_table[hash(p2)].append((i, p2, t[1])) pt_table[hash(p3)].append((i, p3, t[2])) normal = vcross(sub(p2, p1), sub(p3, p1)) normal = vnorm(normal) triangle_normals[i] = normal for key, value in pt_table.iteritems(): # we assume no collisions in the hash point_index = value[0][2] first_point = value[0][1] # compute the normal of each triangles around # TODO should be done just once for each triangle in pre-process normals = [] for t_index, p, _ in value: assert p == first_point normals.append(triangle_normals[t_index]) N = (sum(n[0] for n in normals) / len(normals), sum(n[1] for n in normals) / len(normals), sum(n[2] for n in normals) / len(normals)) # print N out[point_index] = N return out
def compute_normals_hash(sc): out = [] triangle_normals = len(sc.faces) * [[0.0, 0.0, 0.0]] def hash(p): return 0.11234 * p[0] + 0.35678 * p[1] + 0.67257 * p[2] from collections import defaultdict pt_table = defaultdict(list) for i, t in enumerate(sc.faces): p1 = sc.points[t[0]] p2 = sc.points[t[1]] p3 = sc.points[t[2]] pt_table[hash(p1)].append((i, p1, t[0])) pt_table[hash(p2)].append((i, p2, t[1])) pt_table[hash(p3)].append((i, p3, t[2])) normal = vcross(sub(p2, p1), sub(p3, p1)) normal = vnorm(normal) triangle_normals[i] = normal i = 0 normals = [] faces_normals = [] for t in sc.faces: p1 = sc.points[t[0]] p2 = sc.points[t[1]] p3 = sc.points[t[2]] for point in [p1, p2, p3]: # we assume no collisions in the hash value = pt_table[hash(point)] point_index = value[0][2] first_point = value[0][1] # compute the normal of each triangles around # TODO should be done just once for each triangle in pre-process neighbors_normals = [] for t_index, p, _ in value: assert p == first_point neighbors_normals.append(triangle_normals[t_index]) N = ( sum(n[0] for n in neighbors_normals) / len(neighbors_normals), sum(n[1] for n in neighbors_normals) / len(neighbors_normals), sum(n[2] for n in neighbors_normals) / len(neighbors_normals), ) # normalize normal N = vnorm(N) # print N normals.append(N) faces_normals.append((3 * i, 3 * i + 1, 3 * i + 2)) i += 1 return normals, faces_normals