def dual_contour(data, gdata, res, res_fine, dims, coarse_level): # Compute vertices dc_verts = [] vindex = {} dc_manifold_nodes = [] manifold_index = {} for x, y in it.product(np.arange(dims['xmin'], dims['xmax'], res), np.arange(dims['ymin'], dims['ymax'], res)): o = np.array([float(x), float(y)]) quad_signs=[] quad_sign_keys=[] # Get signs for cube for v in quad_verts: position = (o + v*res) quad_sign_keys.append(tuple(position)) for key in quad_sign_keys: c = is_inside(data, key) quad_signs.append(c) if all(quad_signs) or not any(quad_signs): continue # #this checks for certain problematic cases and introduces manifold nodes, if necessary # if coarse_level: # if quad_signs == [False, True, False, True] or quad_signs == [True, False, True, False]: # key = tuple(o) # manifold_index[key] = len(dc_manifold_nodes) # dc_manifold_nodes.append(ManifoldNode(o, quad_sign_keys, data, res)) # Estimate hermite data h_data = [] for e in quad_edges: if quad_signs[e[0]] != quad_signs[e[1]]: v0 = o + quad_verts[e[0]]*res v1 = o + quad_verts[e[1]]*res x, dx = estimate_hermite(data, gdata, v0, v1, res, res_fine, coarse_level) #h_data.append(x) h_data.append(tuple([x,dx])) print "zero crossing from node "+str(v0)+" to "+str(v1) print "\tx:\t"+str(x) print "\tdx:\t"+str(dx) #Solve qef to get vertex A = [n for p, n in h_data] b = [np.dot(p, n) for p, n in h_data] print A print b #quit() v, residue, rank, s = la.lstsq(A, b) # counter = 0 # v = np.array([0.0, 0.0]) # # for p in h_data: # v += np.array(p) # counter += 1 # # v /= 1.0 * counter #Throw out failed solutions if la.norm(v-o) > 2 * res: continue # Emit one vertex per every cube that crosses key = tuple(o) vindex[key] = len(dc_verts) dc_verts.append(v) # Construct faces dc_edges = [] for x, y in it.product(np.arange(dims['xmin'], dims['xmax'], res), np.arange(dims['ymin'], dims['ymax'], res)): # Emit one edge per each edge that crosses if (x, y) in vindex: o = np.array([float(x), float(y)]) for i in range(2): if tuple(o + res*dirs[i]) in vindex: if (data[tuple(o+res*dirs[i]+res*dirs[int(not i)])] > 0) != (data[tuple(o+res*dirs[i])] > 0): dc_edges.append([vindex[tuple(o)], vindex[tuple(o + np.array(dirs[i])*res)]]) else: continue if coarse_level: # if we are working on coarse scale we want to resolve non manifold vertices dc_verts, dc_edges = resolve_manifold_nodes(dc_edges, dc_verts, vindex, dc_manifold_nodes, manifold_index, res, dims) return np.array(dc_verts), np.array(dc_edges)
def dual_contour(data, res, dims, coarse_level): # Compute vertices dc_verts = [] vindex = {} dc_manifold_nodes = [] manifold_index = {} for x, y in it.product(np.arange(dims['xmin'], dims['xmax'], res), np.arange(dims['ymin'], dims['ymax'], res)): o = np.array([float(x), float(y)]) quad_signs=[] quad_sign_keys=[] # Get signs for cube for v in quad_verts: position = (o + v*res) quad_sign_keys.append(tuple(position)) for key in quad_sign_keys: c = True if key in data: c = data[key] > 0 quad_signs.append(c) if all(quad_signs) or not any(quad_signs): continue #this checks for certain problematic cases and introduces manifold nodes, if necessary if coarse_level: if quad_signs == [False, True, False, True] or quad_signs == [True, False, True, False]: key = tuple(o) manifold_index[key] = len(dc_manifold_nodes) dc_manifold_nodes.append(ManifoldNode(o, quad_sign_keys, data, res)) # Estimate hermite data h_data = [] for e in quad_edges: if quad_signs[e[0]] != quad_signs[e[1]]: h_data.append(estimate_hermite(data, o + quad_verts[e[0]]*res, o + quad_verts[e[1]]*res)) counter = 0 v = np.array([0.0, 0.0]) for p in h_data: v += np.array(p) counter += 1 v /= 1.0 * counter # Throw out failed solutions if la.norm(v - o) > 2 * res: continue # Emit one vertex per every cube that crosses key = tuple(o) vindex[key] = len(dc_verts) dc_verts.append(v) # Construct faces dc_edges = [] for x, y in it.product(np.arange(dims['xmin'], dims['xmax'], res), np.arange(dims['ymin'], dims['ymax'], res)): # Emit one edge per each edge that crosses if (x, y) in vindex: o = np.array([float(x), float(y)]) for i in range(2): if tuple(o + res*dirs[i]) in vindex: if (data[tuple(o+res*dirs[i]+res*dirs[int(not i)])] > 0) != (data[tuple(o+res*dirs[i])] > 0): dc_edges.append([vindex[tuple(o)], vindex[tuple(o + np.array(dirs[i])*res)]]) else: continue if coarse_level: # if we are working on coarse scale we want to resolve non manifold vertices dc_verts, dc_edges = resolve_manifold_nodes(dc_edges, dc_verts, vindex, dc_manifold_nodes, manifold_index, res, dims) return np.array(dc_verts), np.array(dc_edges)