def find_triangle(mesh, direction, lighting, sensor): sample_num = direction.shape[0] source = igl.eigen.MatrixXd(np.tile(lighting, (sample_num, 1))) n = igl.eigen.MatrixXd(direction) barycoord = igl.eigen.MatrixXd() barycoord = igl.embree.line_mesh_intersection(source, n, mesh.v, mesh.f) fid = np.array(barycoord.col(0).transpose())[0] idx = list(compress(range(sample_num), fid != -1)) intersection_p = igl.barycentric_to_global(mesh.v, mesh.f, barycoord) intersection_p = np.array(intersection_p) v2 = np.empty((sample_num, 3)) d2 = np.empty(sample_num) v2[idx, :] = sensor - intersection_p[idx, :] d2[idx] = np.sqrt(np.sum(v2[idx, :]**2, axis=1)) v2[idx, :] = element_wise_manipulation.element_divide2(v2[idx, :], d2[idx]) source = igl.eigen.MatrixXd(np.tile(sensor, (len(idx), 1))) n = igl.eigen.MatrixXd(-v2[idx, :]) barycoord2 = igl.eigen.MatrixXd() barycoord2 = igl.embree.line_mesh_intersection(source, n, mesh.v, mesh.f) fid2 = np.array(barycoord2.col(0).transpose())[0] idx = list(compress(idx, fid[idx] != fid2)) fid[idx] = -1 return fid
def mesh_sampling(mesh, barycoord, lighting, sensor, lighting_normal, sensor_normal, opt): mesh_transient = np.zeros(opt.max_distance_bin) fn = np.array(mesh.fn) fid = np.array(barycoord.col(0)) intersection_p = igl.barycentric_to_global(mesh.v, mesh.f, barycoord) source = igl.eigen.MatrixXd(np.tile(lighting, (opt.sample_num,1))) v1 = source - intersection_p d1 = np.array(v1.rowwiseNorm()) v1 = v1.rowwiseNormalized() barycoord1 = igl.eigen.MatrixXd() barycoord1 = igl.embree.line_mesh_intersection(source, -v1, mesh.v, mesh.f) fid1 = np.array(barycoord1.col(0)) idx = list(compress(range(opt.sample_num), fid == fid1)) source = igl.eigen.MatrixXd(np.tile(sensor, (len(idx),1))) intersection_p_subset = igl.eigen.MatrixXd(np.array(intersection_p)[idx,:]) v2 = source - intersection_p_subset d2 = np.array(v2.rowwiseNorm()) v2 = v2.rowwiseNormalized() barycoord2 = igl.eigen.MatrixXd() barycoord2 = igl.embree.line_mesh_intersection(source, -v2, mesh.v, mesh.f) fid2 = np.array(barycoord2.col(0)) idx1 = list(compress(idx, fid1[idx] == fid2)) if len(idx1) == 0: return mesh_transient idx2 = list(compress(range(len(fid2)), fid1[idx] == fid2)) if opt.normal == 'fn': normalMap = mesh.fn[np.hstack(fid2[idx2]).astype(int),:] else: barycoord2 = np.array(barycoord2) barycoord2 = barycoord2[idx2,:] f = np.array(mesh.f) f = f[np.hstack(fid2[idx2]).astype(int),:] normalMap = np.vstack((1-barycoord2[:,1]-barycoord2[:,2]))*mesh.vn[f[:,0],:] + np.vstack(barycoord2[:,1])*mesh.vn[f[:,1],:] + np.vstack(barycoord2[:,2])*mesh.vn[f[:,2],:] cos_theta1 = np.einsum('ij,ij->i', normalMap, np.array(v1)[idx1,:]) cos_theta1[cos_theta1<0] = 0 cos_theta2 = np.einsum('ij,ij->i', normalMap, np.array(v2)[idx2,:]) cos_theta2[cos_theta2<0] = 0 d1_new = np.squeeze(d1[idx1]) d2_new = np.squeeze(d2[idx2]) distance_bin = np.ceil((d1_new + d2_new)/opt.distance_resolution) -1 idx = list(compress(range(len(distance_bin)), distance_bin < opt.max_distance_bin)) intensity = np.divide(cos_theta1*cos_theta2, (d1_new**2)*(d2_new**2)) u = np.unique(distance_bin[idx]) for x in u: mesh_transient[x.astype(int)] += sum(intensity[distance_bin == x]) mesh_transient *= mesh.total_area mesh_transient /= opt.sample_num return mesh_transient
def old_stratified_mesh_sampling_collocate(mesh, lighting, lighting_normal, opt): face_area = np.array(mesh.doublearea)/2 mesh.total_area = sum(face_area) mesh_transient = np.zeros(opt.max_distance_bin) fn = np.array(mesh.fn) for face in range(fn.shape[0]): barycoord = np.ones((opt.sample_num,3))*face barycoord[:,1] = np.random.random(opt.sample_num) barycoord[:,2] = (1 - barycoord[:,1])*np.random.random(opt.sample_num) barycoord = igl.eigen.MatrixXd(barycoord) intersection_p = igl.barycentric_to_global(mesh.v, mesh.f, barycoord) source = igl.eigen.MatrixXd(np.tile(lighting, (opt.sample_num,1))) v1 = source - intersection_p d1 = np.array(v1.rowwiseNorm()) v1 = v1.rowwiseNormalized() barycoord1 = igl.eigen.MatrixXd() barycoord1 = igl.embree.line_mesh_intersection(source, -v1, mesh.v, mesh.f) fid1 = np.array(barycoord1.col(0)) idx = np.hstack((fid1 == face)) if not idx.any(): continue normalMap = np.zeros((opt.sample_num,3)) if opt.normal == 'fn': normalMap[idx,:] = fn[np.hstack(fid1[idx]).astype(int),:] else: barycoord1 = np.array(barycoord1) f = np.array(mesh.f) f = f[np.hstack(fid1[idx]).astype(int),:] normalMap[idx,:] = np.vstack((1-barycoord1[idx,1]-barycoord1[idx,2]))*mesh.vn[f[:,0],:] + np.vstack(barycoord1[idx,1])*mesh.vn[f[:,1],:] + np.vstack(barycoord1[idx,2])*mesh.vn[f[:,2],:] cos_theta1 = np.zeros(opt.sample_num) cos_theta1[idx] = np.einsum('ij,ij->i', normalMap[idx,:], np.array(v1)[idx,:]) cos_theta1[cos_theta1<0] = 0 d1_new = np.squeeze(d1[idx]) distance_bin = np.ones(opt.sample_num)*(opt.distance_resolution) distance_bin[idx] = np.ceil((d1_new *2)/opt.distance_resolution) -1 idx = distance_bin < opt.max_distance_bin intensity = np.zeros(opt.sample_num) d1_new = np.squeeze(d1[idx]) intensity[idx] = np.divide(cos_theta1[idx]**2, (d1_new**4)) u = np.unique(distance_bin[idx]) for x in u: mesh_transient[x.astype(int)] += (sum(intensity[distance_bin == x]))*face_area[face] #mesh_transient[x.astype(int)] += (sum(intensity[distance_bin == x])) #mesh_transient *= face_area.shape[0] #mesh_transient *= mesh.total_area mesh_transient /= opt.sample_num return mesh_transient
def new_render_all_collocate(mesh,opt,barycoord): #barycoord = random_barycoord(mesh, opt.sample_num) measurement_num = opt.lighting.shape[0] mesh_transient = np.zeros((measurement_num, opt.max_distance_bin)) fn = np.array(mesh.fn) fid = np.array(barycoord.col(0).replicate(measurement_num,1)) intersection_p = igl.barycentric_to_global(mesh.v, mesh.f, barycoord).replicate(measurement_num,1) source = igl.eigen.MatrixXd(np.reshape(np.tile(opt.lighting, (1, opt.sample_num)),(opt.sample_num*measurement_num,3))) v1 = source - intersection_p d1 = np.array(v1.rowwiseNorm()) v1 = v1.rowwiseNormalized() barycoord1 = igl.eigen.MatrixXd() barycoord1 = igl.embree.line_mesh_intersection(source, -v1, mesh.v, mesh.f) fid1 = np.array(barycoord1.col(0)) idx = np.hstack((fid == fid1)) f_idx = np.hstack(fid[idx]).astype(int) normalMap = np.zeros((opt.sample_num*measurement_num,3)) if opt.normal == 'fn': normalMap[idx,:] = fn[f_idx,:] else: barycoord1 = np.array(barycoord1) f = np.array(mesh.f) f = f[np.hstack(fid[idx]).astype(int),:] normalMap[idx,:] = np.vstack((1-barycoord1[idx,1]-barycoord1[idx,2]))*mesh.vn[f[:,0],:] + np.vstack(barycoord1[idx,1])*mesh.vn[f[:,1],:] + np.vstack(barycoord1[idx,2])*mesh.vn[f[:,2],:] cos_theta1 = np.zeros(opt.sample_num*measurement_num) cos_theta1[idx] = np.einsum('ij,ij->i', normalMap[idx,:], np.array(v1)[idx,:]) cos_theta1[cos_theta1<0] = 0 d1_new = np.squeeze(d1[idx]) distance_bin = np.ones(opt.sample_num*measurement_num)*(opt.distance_resolution) distance_bin[idx] = np.ceil((d1_new *2)/opt.distance_resolution) -1 idx = distance_bin < opt.max_distance_bin intensity = np.zeros(opt.sample_num*measurement_num) d1_new = np.squeeze(d1[idx]) intensity[idx] = np.divide(cos_theta1[idx]**2, (d1_new**4)) intensity = np.reshape(intensity, (measurement_num, opt.sample_num)) u = np.unique(distance_bin[idx]) for x in u: d_ind = np.reshape(distance_bin == x, (measurement_num, opt.sample_num)) for m in range(measurement_num): mesh_transient[m, x.astype(int)] += sum(intensity[m, d_ind[m,:]]) mesh_transient *= mesh.total_area mesh_transient /= opt.sample_num return mesh_transient
def space_carving_projection(mesh_optimization, space_carving_mesh): v = igl.eigen.MatrixXd(mesh_optimization.v.data.numpy()) direction = igl.eigen.MatrixXd.Zero(v.rows(),3) direction.setCol(2, igl.eigen.MatrixXd.Ones(v.rows(),1)) barycoord = igl.eigen.MatrixXd() barycoord = igl.embree.line_mesh_intersection(v, direction, space_carving_mesh.v, space_carving_mesh.f) point = igl.barycentric_to_global(space_carving_mesh.v, space_carving_mesh.f, barycoord) z = np.array(point.col(2)) z_original = np.array(v.col(2)) for x in list(compress(range(v.rows()), z_original < z)): v.setRow(x, point.row(x)) return v
def space_carving_initialization(mesh, space_carving_mesh, opt): [x, y] = np.meshgrid(np.linspace(-2.2, 1.8, 7), np.linspace(-2.2, 1.8, 7)) x = np.concatenate(x) y = np.concatenate(y) v = np.vstack((x,y,np.ones_like(x)*opt.max_distance_bin*opt.distance_resolution/2)).T tri = Delaunay(v[:,0:2]) mesh.f = igl.eigen.MatrixXi(tri.simplices[:,[0,2,1]]) mesh.v = igl.eigen.MatrixXd(v) direction = igl.eigen.MatrixXd(np.tile(np.array([0,0,1.0]), (mesh.v.rows(), 1))) barycoord = igl.eigen.MatrixXd() barycoord = igl.embree.line_mesh_intersection(mesh.v, direction, space_carving_mesh.v, space_carving_mesh.f) point = igl.barycentric_to_global(space_carving_mesh.v, space_carving_mesh.f, barycoord) fid = np.array(barycoord.col(0)) for x in list(compress(range(mesh.v.rows()), fid != -1)): mesh.v.setRow(x, point.row(x))
def find_triangle(mesh, direction, lighting, sensor, opt): sample_num = direction.shape[0] source = igl.eigen.MatrixXd(np.tile(lighting, (sample_num, 1))) n = igl.eigen.MatrixXd(direction) barycoord = igl.eigen.MatrixXd() barycoord = igl.embree.line_mesh_intersection(source, n, mesh.v, mesh.f) fid = np.array(barycoord.col(0).transpose())[0] idx = list(compress(range(sample_num), fid != -1)) intersection_p = igl.barycentric_to_global(mesh.v, mesh.f, barycoord) intersection_p = np.array(intersection_p) v1 = np.empty((sample_num, 3)) d1 = np.empty(sample_num) v1[idx, :] = lighting - intersection_p[idx, :] d1[idx] = np.sqrt(np.sum(v1[idx, :]**2, axis=1)) v2 = np.empty((sample_num, 3)) d2 = np.empty(sample_num) v2[idx, :] = sensor - intersection_p[idx, :] d2[idx] = np.sqrt(np.sum(v2[idx, :]**2, axis=1)) v2[idx, :] = element_divide2_np(v2[idx, :], d2[idx]) source = igl.eigen.MatrixXd(np.tile(sensor, (len(idx), 1))) n = igl.eigen.MatrixXd(-v2[idx, :]) barycoord2 = igl.eigen.MatrixXd() barycoord2 = igl.embree.line_mesh_intersection(source, n, mesh.v, mesh.f) fid2 = np.array(barycoord2.col(0).transpose())[0] #distance_bin = np.zeros(sample_num) #distance_bin[idx] = np.minimum(np.ceil((d1[idx] + d2[idx])/opt.distance_resolution) -1, opt.max_distance_bin -1 ) idx = list(compress(idx, fid[idx] != fid2)) fid[idx] = -1 #return fid, distance_bin return fid
def render_transient(mesh, lighting, sensor, lighting_normal, sensor_normal, opt, angular_transient): source = igl.eigen.MatrixXd(np.tile(lighting, (opt.sample_num, 1))) phi = 2 * math.pi * np.random.rand(opt.sample_num) theta = np.arccos(np.random.rand(opt.sample_num)) R = np.zeros([3, 3]) rotation_matrix.R_2vect(R, np.array([0, 0, 1]), lighting_normal) direction = np.dot( np.vstack((np.sin(theta) * np.cos(phi), np.sin(theta) * np.sin(phi), np.cos(theta))).T, R.T) n = igl.eigen.MatrixXd(direction) barycoord = igl.eigen.MatrixXd() barycoord = igl.embree.line_mesh_intersection(source, n, mesh.v, mesh.f) fid = np.array(barycoord.col(0)).astype(int) idx = list(compress(range(opt.sample_num), fid != -1)) normalMap = np.empty((opt.sample_num, 3)) normalMap[:] = np.nan v11 = np.empty(opt.sample_num) v11[:] = np.nan d1 = np.empty(opt.sample_num) d1[:] = np.nan v2 = np.empty((opt.sample_num, 3)) v2[:] = np.nan d2 = np.empty(opt.sample_num) d2[:] = np.nan cos_theta2 = np.empty(opt.sample_num) cos_theta2[:] = np.nan distance_bin = np.empty(opt.sample_num) distance_bin[:] = opt.max_distance_bin + 1 intensity = np.empty(opt.sample_num) intensity[:] = np.nan intersection_p = igl.barycentric_to_global(mesh.v, mesh.f, barycoord) intersection_p = np.array(intersection_p) fn = np.array(mesh.fn) normalMap[idx, :] = fn[np.hstack(fid[idx]), :] v11[idx] = lighting[0] - intersection_p[idx, 0] d1[idx] = np.abs(np.divide(v11[idx], direction[idx, 0])) v2[idx, :] = sensor - intersection_p[idx, :] d2[idx] = np.sqrt(np.sum(v2[idx, :]**2, axis=1)) v2[idx, :] = element_divide2_np(v2[idx, :], d2[idx]) source = igl.eigen.MatrixXd(np.tile(sensor, (len(idx), 1))) n = igl.eigen.MatrixXd(-v2[idx, :]) barycoord2 = igl.eigen.MatrixXd() barycoord2 = igl.embree.line_mesh_intersection(source, n, mesh.v, mesh.f) fid2 = np.array(barycoord2.col(0)) idx = list(compress(idx, fid[idx] == fid2)) cos_theta2[idx] = np.einsum('ij,ij->i', normalMap[idx, :], v2[idx, :]) less_than_zero = list(compress(idx, cos_theta2[idx] < 0)) if len(less_than_zero) != 0: cos_theta2[less_than_zero] = 0 distance_bin[idx] = np.ceil( (d1[idx] + d2[idx]) / opt.distance_resolution) - 1 inds = list( compress(range(opt.sample_num), distance_bin < opt.max_distance_bin)) intensity[inds] = np.divide(cos_theta2[inds], d2[inds]**2) u = np.unique(distance_bin[inds]) for x in u: angular_transient[x.astype(int)] += sum(intensity[distance_bin == x]) angular_transient *= 2 * math.pi angular_transient /= opt.sample_num
def mesh_grad_sampling(mesh, barycoord, lighting, sensor, lighting_normal, sensor_normal, opt): fn = np.array(mesh.fn) face_area = np.array(mesh.doublearea)/2 grad = np.zeros((opt.max_distance_bin, 3*mesh.v.rows())) for vertex in range(mesh.v.rows()): related_face = list(compress(range(mesh.f.rows()), np.sum(np.array(mesh.f) == vertex, 1) > 0 )) for f in related_face: face = np.array(mesh.f.row(f))[0] vertex_idx = list(compress(range(3), face == vertex)) vertex_idx = vertex_idx[0] ind = np.squeeze(np.array(barycoord.col(0)) == f) sample_num = np.sum(ind) if sample_num == 0: continue u = np.array(barycoord.col(1))[ind,:] v = np.array(barycoord.col(2))[ind,:] phi = 1-u-v barycoord_subset = igl.eigen.MatrixXd(np.array(barycoord)[ind,:]) sample_point = igl.barycentric_to_global(mesh.v, mesh.f, barycoord_subset) source = igl.eigen.MatrixXd(np.tile(lighting, (sample_num, 1))) v1 = source - sample_point d1 = np.array(v1.rowwiseNorm()) v1 = v1.rowwiseNormalized() barycoord1 = igl.eigen.MatrixXd() barycoord1 = igl.embree.line_mesh_intersection(source, -v1, mesh.v, mesh.f) fid1 = np.array(barycoord1.col(0)) idx = list(compress(range(sample_num), fid1 == f)) if len(idx) == 0: continue source = igl.eigen.MatrixXd(np.tile(sensor, (len(idx),1))) sample_point_subset = igl.eigen.MatrixXd(np.array(sample_point)[idx,:]) v2 = source - sample_point_subset d2 = np.array(v2.rowwiseNorm()) v2 = v2.rowwiseNormalized() barycoord2 = igl.eigen.MatrixXd() barycoord2 = igl.embree.line_mesh_intersection(source, -v2, mesh.v, mesh.f) fid2 = np.array(barycoord2.col(0)) idx1 = list(compress(idx, fid2 == f)) if len(idx1) == 0: continue idx2 = list(compress(range(len(fid2)), fid2 == f)) normalMap = fn[f,:] u_new = u[idx1] v_new = v[idx1] phi_new = phi[idx1] v1_new = np.array(v1)[idx1,:] v2_new = np.array(v2)[idx2,:] cos_theta1 = np.dot(v1_new, normalMap) cos_theta1[cos_theta1<0] = 0 cos_theta2 = np.dot(v2_new, normalMap) cos_theta2[cos_theta2<0] = 0 d1_new = np.squeeze(d1[idx1]) d2_new = np.squeeze(d2[idx2]) distance_bin = np.ceil((d1_new + d2_new)/opt.distance_resolution) -1 intensity = np.divide(cos_theta1*cos_theta2, (d1_new**2)*(d2_new**2)) if isinstance(distance_bin, np.float64): if distance_bin >= opt.max_distance_bin: continue else: intensity = np.array(intensity) d1_new = np.array([d1_new]) d2_new = np.array([d2_new]) cos_theta1 = np.array(cos_theta1) cos_theta2 = np.array(cos_theta2) phi_new = np.array(phi_new) u_new = np.array(u_new) v_new = np.array(v_new) distance_bin = np.array([distance_bin]) idx = [0] else: idx = list(compress(range(len(distance_bin)), distance_bin < opt.max_distance_bin)) if len(idx) == 0: continue gx1_tmp = d2_new[idx]*cos_theta2[idx] + d1_new[idx]*cos_theta1[idx] gx1 = normalMap*np.vstack(gx1_tmp) gx2_tmp1 = v1_new[idx,:]*np.vstack(d2_new[idx]) + v2_new[idx,:]*np.vstack(d1_new[idx]) gx2_tmp2 = cos_theta1[idx] * cos_theta2[idx] gx2 = gx2_tmp1*np.vstack(gx2_tmp2) t1_tmp1 = -gx1+3*gx2 t1_tmp2 = (d1_new[idx]**3)*(d2_new[idx]**3) t1 = t1_tmp1/np.vstack(t1_tmp2) t2 = normalMap*np.vstack(intensity[idx]) gn_tmp1 = v1_new[idx,:]*np.vstack(cos_theta2[idx]) + v2_new[idx,:]*np.vstack(cos_theta1[idx]) gn_tmp2 = (d1_new[idx]**2)*(d2_new[idx]**2) gn_tmp = gn_tmp1/np.vstack(gn_tmp2) cos_tmp = np.dot(gn_tmp, normalMap) gn = gn_tmp - normalMap*np.vstack(cos_tmp) t2 = (t2 + gn)/(2*face_area[f]) if vertex_idx == 0: e = np.array(mesh.v.row(face[2]) - mesh.v.row(face[1])) g = t1*phi_new[idx] + np.cross(t2, e) elif vertex_idx == 1: e = np.array(mesh.v.row(face[0]) - mesh.v.row(face[2])) g = t1*u_new[idx] + np.cross(t2, e) else: e = np.array(mesh.v.row(face[1]) - mesh.v.row(face[0])) g = t1*v_new[idx] + np.cross(t2, e) distance_new = distance_bin[idx] unique_bin = np.unique(distance_new) for x in unique_bin: grad[x.astype(int),3*vertex:3*(vertex+1)] += np.sum(g[distance_new == x,:],0)*face_area[f] grad /= opt.sample_num return grad
def new_mesh_grad_sampling_collocate(mesh, barycoord, lighting, lighting_normal, opt): fn = np.array(mesh.fn) face_area = np.array(mesh.doublearea)/2 grad = np.zeros((opt.max_distance_bin, 3*mesh.v.rows())) sample_num = opt.sample_num fid = np.array(barycoord.col(0)) u = np.array(barycoord.col(1)) v = np.array(barycoord.col(2)) phi = 1-u-v sample_point = igl.barycentric_to_global(mesh.v, mesh.f, barycoord) source = igl.eigen.MatrixXd(np.tile(lighting, (sample_num,1))) v1 = source-sample_point d1 = np.array(v1.rowwiseNorm()) v1 = v1.rowwiseNormalized() sample_point = np.array(sample_point) barycoord1 = igl.eigen.MatrixXd() barycoord1 = igl.embree.line_mesh_intersection(source, -v1, mesh.v, mesh.f) v1 = np.array(v1) fid1 = np.array(barycoord1.col(0)) visible_idx = np.hstack((fid1 == fid)) f_idx = np.hstack(fid[visible_idx]).astype(int) normalMap = np.empty((sample_num, 3)) normalMap[visible_idx,:] = fn[f_idx,:] cos_theta1 = np.zeros(sample_num) cos_theta1[visible_idx] = np.einsum('ij,ij->i', normalMap[visible_idx,:], np.array(v1)[visible_idx,:]) cos_theta1[cos_theta1<0] = 0 d1_new = np.squeeze(d1[visible_idx]) distance_bin = np.ones(sample_num) * (opt.max_distance_bin + 1) distance_bin[visible_idx] = np.ceil((d1_new *2)/opt.distance_resolution) -1 visible_idx = (distance_bin < opt.max_distance_bin) fid[distance_bin >= opt.max_distance_bin] = -1 intensity = np.empty(sample_num) d1_new = np.squeeze(d1[visible_idx]) intensity[visible_idx] = np.divide(cos_theta1[visible_idx]**2, (d1_new**4)) face_num = mesh.f.rows() for vertex in range(mesh.v.rows()): related_face = list(compress(range(face_num), np.sum(np.array(mesh.f) == vertex, 1) > 0 )) for f in related_face: face = np.array(mesh.f.row(f))[0] vertex_idx = list(compress(range(3), face == vertex)) vertex_idx = vertex_idx[0] ind = np.squeeze(fid == f) sample_num = np.sum(ind) if sample_num == 0: continue u_new = u[ind,:] v_new = v[ind,:] phi_new = phi[ind] sample_point_new = sample_point[ind,:] d1_new = d1[ind] v1_new = v1[ind,:] normalMap_new = fn[f,:] cos_theta1_new = cos_theta1[ind] distance_bin_new = distance_bin[ind] intensity_new = intensity[ind] t1_tmp1 = 6*v1_new*np.vstack(cos_theta1_new**2) - 2*normalMap_new*np.vstack(cos_theta1_new) t1 = t1_tmp1/np.vstack(d1_new**5) t2 = normalMap_new*np.vstack(intensity_new) gn_tmp1 = 2*v1_new*np.vstack(cos_theta1_new) gn_tmp = gn_tmp1/np.vstack(d1_new**4) cos_tmp = np.dot(gn_tmp, normalMap_new) gn = gn_tmp - normalMap_new*np.vstack(cos_tmp) t2 = (t2 + gn)/(2*face_area[f]) if vertex_idx == 0: e = np.array(mesh.v.row(face[2]) - mesh.v.row(face[1])) g = t1*phi_new + np.cross(t2, e) elif vertex_idx == 1: e = np.array(mesh.v.row(face[0]) - mesh.v.row(face[2])) g = t1*u_new + np.cross(t2, e) else: e = np.array(mesh.v.row(face[1]) - mesh.v.row(face[0])) g = t1*v_new + np.cross(t2, e) unique_bin = np.unique(distance_bin_new) for x in unique_bin: grad[x.astype(int),3*vertex:3*(vertex+1)] += np.sum(g[distance_bin_new == x,:],0)*face_area[f] grad /= opt.sample_num return grad
def angular_sampling(mesh, direction, lighting, sensor, lighting_normal, sensor_normal, opt): source = igl.eigen.MatrixXd(np.tile(lighting, (opt.sample_num, 1))) n = igl.eigen.MatrixXd(direction) angular_transient = np.zeros(opt.max_distance_bin) barycoord = igl.eigen.MatrixXd() barycoord = igl.embree.line_mesh_intersection(source, n, mesh.v, mesh.f) fid = np.array(barycoord.col(0)).astype(int) idx = list(compress(range(opt.sample_num), fid != -1)) normalMap = np.empty((opt.sample_num, 3)) normalMap[:] = np.nan v11 = np.empty(opt.sample_num) v11[:] = np.nan d1 = np.empty(opt.sample_num) d1[:] = np.nan v2 = np.empty((opt.sample_num, 3)) v2[:] = np.nan d2 = np.empty(opt.sample_num) d2[:] = np.nan cos_theta2 = np.empty(opt.sample_num) cos_theta2[:] = np.nan distance_bin = np.empty(opt.sample_num) distance_bin[:] = opt.max_distance_bin + 1 intensity = np.empty(opt.sample_num) intensity[:] = np.nan intersection_p = igl.barycentric_to_global(mesh.v, mesh.f, barycoord) intersection_p = np.array(intersection_p) normalMap[idx, :] = mesh.fn[np.hstack(fid[idx]), :] v11[idx] = lighting[0] - intersection_p[idx, 0] d1[idx] = np.abs(np.divide(v11[idx], direction[idx, 0])) v2[idx, :] = sensor - intersection_p[idx, :] d2[idx] = np.sqrt(np.sum(v2[idx, :]**2, axis=1)) v2[idx, :] = element_wise_manipulation.element_divide2(v2[idx, :], d2[idx]) source = igl.eigen.MatrixXd(np.tile(sensor, (len(idx), 1))) n = igl.eigen.MatrixXd(-v2[idx, :]) barycoord2 = igl.eigen.MatrixXd() barycoord2 = igl.embree.line_mesh_intersection(source, n, mesh.v, mesh.f) fid2 = np.array(barycoord2.col(0)) idx = list(compress(idx, fid[idx] == fid2)) cos_theta2[idx] = np.einsum('ij,ij->i', normalMap[idx, :], v2[idx, :]) less_than_zero = list(compress(idx, cos_theta2[idx] < 0)) if len(less_than_zero) != 0: cos_theta2[less_than_zero] = 0 distance_bin[idx] = np.ceil( (d1[idx] + d2[idx]) / opt.distance_resolution) - 1 inds = list( compress(range(opt.sample_num), distance_bin <= opt.max_distance_bin)) intensity[inds] = np.divide(cos_theta2[inds], d2[inds]**2) u = np.unique(distance_bin[inds]) for x in u: angular_transient[x.astype(int)] += sum(intensity[distance_bin == x]) angular_transient *= 2 * math.pi angular_transient /= opt.sample_num return angular_transient