import rhinoscriptsyntax as rs import random, math import DM_lib as dm def create_building(): vectors = [] for panels in UnoPanelCoords: for panel in panels: curve = rs.AddPolyline(panel + [panel[0]]) vectors.append(curve) rs.ObjectColor(curve, [200, 200, 200]) return vectors def create_portrait_points(pixels, t, origin, initial_positions): points = [] height = len(pixels) width = len(pixels[0]) portrait_height = floorHeight * H portrait_width = lenY offset_y = 2 point_index = 0 for y in range(0, height, 4): for x in range(0, width, 4): if y < len(pixels) and x < len(pixels[y]): color = pixels[y][x] brightness = sum(color) / 3.0 if brightness < 5: continue norm_x = (x / float(width)) * portrait_width norm_z = (1.0 - y / float(height)) * portrait_height target_pos = rs.VectorAdd( origin, rs.VectorAdd( rs.VectorScale(lengthVec, norm_x), rs.VectorAdd( rs.VectorScale(depthVec, offset_y), [0, 0, norm_z] ) ) ) if point_index < len(initial_positions): start_pos = initial_positions[point_index] else: start_pos = [ origin[0] + random.uniform(-lenY, lenY), origin[1] + random.uniform(-lenX*2, lenX*2), origin[2] + random.uniform(0, floorHeight * H) ] initial_positions.append(start_pos) ease = 3*t*t - 2*t*t*t pos = [ start_pos[0] * (1-ease) + target_pos[0] * ease, start_pos[1] * (1-ease) + target_pos[1] * ease, start_pos[2] * (1-ease) + target_pos[2] * ease ] if brightness > 200: color = [255, 215, 0] elif sum([c > 180 for c in color]) >= 2: color = [218, 165, 32] pt = rs.AddPoint(pos) rs.ObjectColor(pt, color) points.append(pt) point_index += 1 return points def create_row_wrapping_points(pixels, origin, row, t): points = [] height = len(pixels) width = len(pixels[0]) portrait_height = floorHeight * H portrait_width = lenY wrap_angle = t * 720 for x in range(0, width, 4): if row < len(pixels) and x < len(pixels[row]): color = pixels[row][x] brightness = sum(color) / 3.0 if brightness < 5: continue norm_x = (x / float(width)) * portrait_width norm_z = (1.0 - row / float(height)) * portrait_height angle_offset = (row / float(height)) * 360 current_angle = wrap_angle + angle_offset radius = lenX * 2 point_x = origin[0] + radius * math.cos(math.radians(current_angle)) + \ rs.VectorScale(lengthVec, norm_x)[0] point_y = origin[1] + radius * math.sin(math.radians(current_angle)) + \ rs.VectorScale(lengthVec, norm_x)[1] point_z = origin[2] + norm_z pt = rs.AddPoint([point_x, point_y, point_z]) if brightness > 200: color = [255, 215, 0] elif sum([c > 180 for c in color]) >= 2: color = [218, 165, 32] rs.ObjectColor(pt, color) points.append([point_x, point_y, point_z]) return points def animate_klimt(frames=60): rs.Command("-_SetDisplayMode _Rendered") target_pos = dm.uno0 dm.newEmptyLayer("endabgabe", [120,120,140]) pixels = dm.getPixels("klimt.jpg", steps_x=2, steps_y=2)[::-1] initial_positions = [] final_image_points = [] wrap_frames = frames // 3 settle_frames = frames // 3 hold_frames = frames // 6 dissolve_frames = frames // 6 rs.Command("_SelNone") rs.Command("_View _Front") for frame in range(frames): rs.EnableRedraw(False) rs.DeleteObjects(rs.ObjectsByLayer("endabgabe")) t = frame / float(frames) angle = 225 - t * 180 base_radius = max(lenX, lenY) * 12 if frame >= wrap_frames + settle_frames + hold_frames: dissolve_t = (frame - (wrap_frames + settle_frames + hold_frames)) / float(dissolve_frames) radius = base_radius * (1 + dissolve_t * 0.5) height = floorHeight * H * (1.5 + dissolve_t * 0.5) else: radius = base_radius height = floorHeight * H * 1.5 cam_x = target_pos[0] + radius * math.cos(math.radians(angle)) cam_y = target_pos[1] + radius * math.sin(math.radians(angle)) cam_z = height + height * 0.2 * math.sin(t * 8) lens = 20 dm.setCameraTarget([cam_x, cam_y, cam_z], target_pos, lens=lens) building = create_building() if frame < wrap_frames + settle_frames: t_combined = frame / float(wrap_frames + settle_frames) height = len(pixels) rows_to_show = height last_positions = [] for row in range(rows_to_show): if row % 4 == 0: wrap_duration = wrap_frames / height * 1.5 row_start = row * wrap_frames / height * 0.8 row_t = min(1.0, (frame - row_start) / wrap_duration) if row_t > 0: points = create_row_wrapping_points(pixels, target_pos, row, row_t) last_positions.extend(points) if frame == wrap_frames - 1: initial_positions = last_positions elif frame < wrap_frames + settle_frames + hold_frames: if frame == wrap_frames + settle_frames and not final_image_points: points = create_portrait_points(pixels, 1.0, target_pos, initial_positions) final_image_points = [(rs.PointCoordinates(pt), rs.ObjectColor(pt)) for pt in points] else: for pos, color in final_image_points: pt = rs.AddPoint(pos) rs.ObjectColor(pt, color) else: t_dissolve = (frame - wrap_frames - settle_frames - hold_frames) / float(dissolve_frames) if t_dissolve < 0.98: for pos, color in final_image_points: if random.random() > pow(t_dissolve, 0.5): rand_vec = [random.uniform(-1, 1) * lenY * t_dissolve * 5 for _ in range(3)] new_pos = rs.VectorAdd(pos, rand_vec) pt = rs.AddPoint(new_pos) fade_factor = max(0, 1 - t_dissolve * 1.5) fade_color = [max(0, min(255, int(c * fade_factor))) for c in color] rs.ObjectColor(pt, fade_color) rs.EnableRedraw(True) rs.Sleep(20) # Building setup floors = H = dm.H = 40 slabs = L = dm.L = 11 depth = D = dm.D = 4 floorHeight = fH = dm.fH = 4.0 lenY = 87.5 lenX = 22.0 UnoGridCoords = dm.getUnoGridCoords(L, D, H, fH) UnoPanelCoords = dm.getUNpanelCoords(anzL=10, anzH=39, anzD=3, stepL=1, stepH=3, stepD=1) lengthVec = rs.VectorUnitize(rs.VectorSubtract(dm.getUnoCoord(1, 0, 0), dm.getUnoCoord(0, 0, 0))) depthVec = rs.VectorUnitize(rs.VectorSubtract(dm.getUnoCoord(0, 1, 0), dm.getUnoCoord(0, 0, 0))) animate_klimt(60)