def make_verts(indices): nonlocal vert_indices v1, v2 = V(verts[indices[0]]), V(verts[indices[1]]) M = (v1 - v2).length real = M / (on + off) rounded = floor(real) diff = real - rounded # make rounded number of on-off segments _a = on / M _b = off / M if diff > 0: rounded += 1 for i in range(rounded): a = i * (_a + _b) b = a + _a va = v1.lerp(v2, a)[:] vb = v1.lerp(v2, min(1, b))[:] add_v(va) add_v(vb) add_e([vert_indices, vert_indices + 1]) vert_indices += 2
def compute_distances_np(line, pts, result, gates, tolerance): '''calculate all distances with NumPy''' # Adapted from https://math.stackexchange.com/questions/1905533/find-perpendicular-distance-from-point-to-line-in-3d np_pts = array(pts) segment = V(line[-1]) - V(line[0]) segment_length = segment.length line_direction = segment / segment_length vect = np_pts - line[0] vect_proy = vect.dot(line_direction) closest_point = line[0] + vect_proy[:, newaxis] * line_direction dif_v = closest_point - np_pts dist = np_norm(dif_v, axis=1) is_in_segment = [] is_in_line = [] closest_in_segment = [] if gates[4] or gates[1]: closest_in_segment = np_all( [vect_proy >= 0, vect_proy <= segment_length], axis=0) if gates[1] or gates[2]: np_tolerance = array(tolerance) is_in_line = dist < tolerance if gates[1]: is_in_segment = np_all([closest_in_segment, is_in_line], axis=0) local_result = [ dist, is_in_segment, is_in_line, closest_point, closest_in_segment ] for i, res in enumerate(result): if gates[i]: res.append( local_result[i].tolist() if not gates[5] else local_result[i])
def compute_intersect_plane_plane(params, result, gates): plane_co_a, plane_norm_a, plane_co_b, plane_norm_b = params local_result = [] plane_co_a_V = V(plane_co_a) plane_norm_a_V = V(plane_norm_a) plane_co_b_V = V(plane_co_b) plane_norm_b_V = V(plane_norm_b) inter_p = intersect_plane_plane(plane_co_a_V, plane_norm_a_V, plane_co_b_V, plane_norm_b_V) if inter_p[0]: intersect = True line_origin = list(inter_p[0]) line_direction = list(inter_p[1]) else: print("Plane Intersection Warning: Planes are parallel") intersect = False line_origin = list(plane_co_a_V) line_direction = list(plane_norm_a_V) local_result =[intersect, line_origin, line_direction] for i, r in enumerate(result): if gates[i]: r.append(local_result[i])
def compute_barycentric_transform_mu(params, result): '''Port to MathUtils barycentric transform function''' tri_src = [V(v) for v in params[2]] tri_dest = [V(v) for v in params[3]] sub_result = [] for vert in params[0]: point = V(vert) new_vert = barycentric_transform(point, tri_src[0], tri_src[1], tri_src[2], tri_dest[0], tri_dest[1], tri_dest[2]) sub_result.append(list(new_vert)) result.append(sub_result)
def compute_distances_mu(line, pts, result, gates, tolerance): '''calculate all distances with mathuutils''' line_origin = V(line[0]) line_end = V(line[-1]) local_result = [[], [], [], [], []] for point in pts: data = compute_distance(V(point), line_origin, line_end, tolerance) for i, res in enumerate(local_result): res.append(data[i]) for i, res in enumerate(result): if gates[i]: res.append(local_result[i])
def compute_distances_mu(plane, pts, result, gates, tolerance): plane_origin = V(plane[0]) plane_a, plane_b = V(plane[1]), V(plane[2]) norm = normal([plane_origin, plane_a, plane_b]) if norm.length == 0: print("Error: the three points of the plane are aligned. Not valid plane") local_result = [[] for res in result] for p in pts: data = compute_point_tri_dist(V(p), plane_origin, plane_a, plane_b, norm, tolerance) for i, r in enumerate(local_result): r.append(data[i]) for i, res in enumerate(result): if gates[i]: res.append(local_result[i])
def compute_intersect_circle_circle(params, result, gates): '''Compute two circles intersection(s) Result has to be [[],[],[]] to host the solutions Gates are as follow: 0: Is there a intersection? 1: First Intersection 2: Second intersection 3: The working plane is defined by its normal (True) or by a third point (False)''' center_a, radius_a, center_b, radius_b, plane_pt, plane_normal = params local_result = [] sphere_loc_a = V(center_a) sphere_loc_b = V(center_b) if gates[3]: norm = V(plane_normal).normalized() else: v_in_plane = V(plane_pt) norm = normal([sphere_loc_a, sphere_loc_b, v_in_plane]) if norm.length == 0: if gates[3]: print("Circle Intersection Error: the Normal can't be (0,0,0)") else: print("Circle Intersection Error: the point in plane is aligned with origins") is_2d = norm.x == 0 and norm.y == 0 if is_2d and False: z_coord = sphere_loc_a.z inter_p = intersect_sphere_sphere_2d(sphere_loc_a.to_2d(), radius_a, sphere_loc_b.to_2d(), radius_b) if inter_p[0]: intersect = True vec1 = list(inter_p[1]) + [z_coord] vec0 = list(inter_p[0]) + [z_coord] local_result = [intersect, vec0, vec1] else: dist = (sphere_loc_a - sphere_loc_b).length new_a = V([0, 0, 0]) new_b = V([dist, 0, 0]) inter_p = intersect_sphere_sphere_2d(new_a.to_2d(), radius_a, new_b.to_2d(), radius_b) if inter_p[0]: intersect_num = True trird_point = sphere_loc_a + norm new_c = V([0, 0, 1]) vec0 = barycentric_transform(inter_p[0].to_3d(), new_a, new_b, new_c, sphere_loc_a, sphere_loc_b, trird_point) vec1 = barycentric_transform(inter_p[1].to_3d(), new_a, new_b, new_c, sphere_loc_a, sphere_loc_b, trird_point) local_result = [intersect_num, list(vec0), list(vec1)] if not local_result: direc = (sphere_loc_b - sphere_loc_a).normalized() intersect_num = False vec0 = sphere_loc_a + direc * radius_a vec1 = sphere_loc_b - direc * radius_b local_result = [intersect_num, list(vec0), list(vec1)] for i, res in enumerate(result): if gates[i]: res.append(local_result[i])
def iteration(vers, facs, scal): overts = [] ofaces = [] for ov, of in zip(vers, facs): lv = len(ov) overts_ = ov ofaces_ = [] fcs = [] for f in of: vrts = [ov[i] for i in f] norm = nm(V(ov[f[0]]), V(ov[f[1]]), V(ov[f[2]])) nv = np.array(vrts) vrt = (nv.sum(axis=0) / len(f)) + np.array(norm * scal) fcs = [[i, k, lv] for i, k in zip(f, f[-1:] + f[:-1])] overts_.append(vrt.tolist()) ofaces_.extend(fcs) lv += 1 overts.append(overts_) ofaces.append(ofaces_) return overts, ofaces, scale * multi
def bmeshing(cut_me_vertices, cut_me_polygons): # create bmesh and selected geometry for bisect it bm = bmesh.new() bm_verts = [bm.verts.new(V(v)) for v in cut_me_vertices] for face in cut_me_polygons: bm.faces.new([bm_verts[i] for i in face]) bm.verts.ensure_lookup_table() bm.edges.ensure_lookup_table() bm.faces.ensure_lookup_table() geom_in = bm.verts[:] + bm.edges[:] + bm.faces[:] return bm, geom_in
def bisec(bm, geom_in, zb): # main section function #bm.verts.index_update() #bm.edges.index_update() #bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.00001) bm.verts.ensure_lookup_table() bm.edges.ensure_lookup_table() bm.faces.ensure_lookup_table() bm.verts.index_update() bm.edges.index_update() bm.faces.index_update() res = bmesh.ops.bisect_plane(bm, geom=geom_in, dist=0.00001, plane_co=V((0.0, 0.0, zb)), plane_no=V((0.0, 0.0, 1.0)), use_snap_center=False, clear_outer=True, clear_inner=True) # res = dict(geom_cut=[], geom=[]) #bm.verts.index_update() #bm.edges.index_update() #print(res) edges = [] verts = [] bm.verts.index_update() bm.edges.index_update() bm.faces.index_update() #vets = {} for k in res['geom']: if isinstance(k, bmesh.types.BMVert): #verts[v.index] = bm.append(k.co) verts.append(k.co[:]) else: edges.append([v.index for v in k.verts[:]]) #edges = [[i,i+1] for i in range(len(verts)-1)] #edges.append([len(verts)-1,0]) #verts = [i.co[:] for i in bm.verts] #print('bisectualism . . . . . . . . . . . .',edges,verts) return verts, edges
material("IfcFurnishingElement", {"diffuse_color": [0.8, 0.7, 0.5]}) material("IfcBuildingElementPro", {"diffuse_intensity": 0.6}) def create_lamp(eul): l = bpy.data.lamps.new('l', 'SUN') l.energy = 1.3 l_ob = bpy.data.objects.new('l', l) scn.objects.link(l_ob) l_ob.rotation_euler = [radians(e) for e in eul] create_lamp((20, 0, 60)) create_lamp((0, -120, -50)) A = V([1e9] * 3) B = V([-1e9] * 3) for ob in scn.objects: if ob.type != 'MESH': continue if ob.hide: continue bb = [ob.matrix_world * V(x) for x in ob.bound_box] for b in bb: for i in range(3): if b[i] < A[i]: A[i] = b[i] if b[i] > B[i]: B[i] = b[i] C = V((1.2, -1.2, 0.6)) D = B - A E = max(D) * C + (A + B) / 2
def compare(v1, v2, v3): # if vertex between points on same line = True vec, isit = IPL(V(v1), V(v2), V(v3)) same = v1 == v2 or v1 == v3 return same, isit