import numpy as np import matplotlib.pyplot as plt import matplotlib.patches as patches from shapely import geometry from .utils import room_label def get_color_map(): color = np.array([ [244,242,229], # living room [253,244,171], # bedroom [234,216,214], # kitchen [205,233,252], # bathroom [208,216,135], # balcony [249,222,189], # Storage [ 79, 79, 79], # exterior wall [255,225, 25], # FrontDoor [128,128,128], # interior wall [255,255,255] ],dtype=np.int64) cIdx = np.array([1,2,3,4,1,2,2,2,2,5,1,6,1,10,7,8,9,10])-1 return color[cIdx] cmap = get_color_map()/255.0 def get_figure(size=512): if np.array(size).size==1: w,h = size,size else: w,h = size[0],size[1] fig = plt.figure() dpi = fig.get_dpi() fig.set_size_inches(w/dpi,h/dpi) fig.set_frameon(False) return fig def get_axes(size=512,fig=None,rect=[0,0,1,1]): if fig is None: fig = get_figure(size) ax = fig.add_axes(rect) #ax.set_frame_on(False) ax.set_aspect('equal') ax.set_xlim([0,255]) ax.set_ylim([0,255]) ax.invert_yaxis() ax.set_axis_off() return ax def plot_category(category,show_boundary=True,ax=None): if ax is None: ax = get_axes() img = np.ones((category.shape[0],category.shape[1],4)) img[...,:3] = cmap[category] img[category==13,3] = 0 if not show_boundary: img[np.isin(category,[14,15])]=[1.,1.,1.,0.] ax.imshow(img) return ax def plot_boundary(boundary, wall_thickness=6,ax=None): if ax is None: ax = get_axes() is_new = boundary[:,-1]==1 poly_boundary = geometry.Polygon(boundary[~is_new,:2]) x,y = poly_boundary.exterior.xy ax.fill(x,y,fc='none',ec=cmap[14],lw=wall_thickness,joinstyle='round') door = boundary[:2,:2] idx = np.argmin(np.sum(door,axis=-1), axis=0) if idx==1: door = door[[1,0]] ori = boundary[0,2] if ori%2==0: door = door+np.array([ [wall_thickness/4,0],[-wall_thickness/4,0] ]) else: door = door+np.array([ [0,wall_thickness/4], [0,-wall_thickness/4] ]) ax.plot(door[:,0],door[:,1],color=cmap[15],lw=wall_thickness+1) return ax def plot_graph(boundary, boxes, types, edges, wall_thickness=6,with_boundary=True,ax=None): if ax is None: ax = get_axes() if with_boundary: plot_boundary(boundary,wall_thickness,ax) boxes = boxes.astype(float) r_node = np.zeros((len(boxes),3)) for k in range(len(boxes)): r_node[k,:2] = (boxes[k,:2]+boxes[k,2:])/2 r_node[k,2] = (boxes[k,2]-boxes[k,0])*(boxes[k,3]-boxes[k,1]) for i in range(len(edges)): idx = edges[i,:2] ax.plot(r_node[idx,0],r_node[idx,1],'-',color=[0.7,0.7,0.7],lw=wall_thickness/2) is_new = boundary[:,-1]==1 poly_boundary = geometry.Polygon(boundary[~is_new,:2]) for i in range(len(r_node)): s = round(10*r_node[i,2])/poly_boundary.area*3+wall_thickness*3 ax.plot(r_node[i,0],r_node[i,1],'o',mec=cmap[16],mfc=cmap[types[i]],ms=s) return ax def plot_fp(boundary, boxes, types, doors=[], windows=[], wall_thickness=6, fontsize=0, keep_box=False, alpha=1.0, ax=None): if ax is None: ax = get_axes() is_new = boundary[:,-1]==1 poly_boundary = geometry.Polygon(boundary[~is_new,:2]) poly = dict() for k in range(len(boxes)): poly_room = geometry.box(*boxes[k]) poly[k] = poly_boundary.intersection(poly_room) if poly[k].area==0: print(f'ploting empty box {k}!') continue if keep_box: poly[k] = geometry.box(*poly[k].bounds) x,y = poly[k].exterior.xy ax.fill(x,y,fc=cmap[types[k]],ec=cmap[16],alpha=alpha,lw=wall_thickness,joinstyle='round') else: if poly[k].geom_type!='Polygon': for p in poly[k]: if p.geom_type!='Polygon': continue x,y = p.exterior.xy ax.fill(x,y,fc=cmap[types[k]],ec=cmap[16],alpha=alpha,lw=wall_thickness,joinstyle='round') else: x,y = poly[k].exterior.xy ax.fill(x,y,fc=cmap[types[k]],ec=cmap[16],alpha=alpha,lw=wall_thickness,joinstyle='round') plot_boundary(boundary,wall_thickness,ax) if len(doors)>0: plot_door(doors, wall_thickness/3, ax) if len(windows)>0: plot_window(windows, wall_thickness/3, ax) if fontsize!=0: for k in range(len(boxes)): if poly[k].area==0: continue cx, cy = poly[k].centroid.x,poly[k].centroid.y ax.text(cx, cy, room_label[types[k]][1], fontsize=fontsize,horizontalalignment='center',verticalalignment='center') return ax def plot_window(windows, thickness=2, ax=None): if ax is None: ax = get_axes() for k in range(len(windows)): window = windows[k] seg = np.zeros((2,2)) seg[0] = window[1:3] seg[1] = window[1:3]+ window[3:5] box = np.concatenate([seg.min(0),seg.max(0)],axis=-1) if window[3] < window[4]: box = box + np.array([-1,0,1,0]) * thickness if window[4] > 0: box[1] = box[1] + thickness seg[0,1] = seg[0,1] + thickness else: box[3] = box[3] - thickness seg[0,1] = seg[0,1] - thickness else: box = box + np.array([0,-1,0,1]) * thickness if window[3] > 0: box[0] = box[0] + thickness seg[0,0] = seg[0,0] + thickness else: box[2] = box[2] - thickness seg[0,0] = seg[0,0] - thickness ax.fill(box[[0,0,2,2,0]], box[[1,3,3,1,1]], 'w') ax.plot(box[[0,0,2,2,0]], box[[1,3,3,1,1]], color=[0.4,0.4,0.4], lw=1) ax.plot(seg[:,0], seg[:,1], color=[0.4,0.4,0.4], lw=1) return ax def plot_door(doors, thickness, ax=None): if ax is None: ax = get_axes() for k in range(len(doors)): door = doors[k] seg = np.zeros((2,2)) seg[0] = door[1:3] seg[1] = door[1:3]+ door[3:5] box = np.concatenate([seg.min(0),seg.max(0)],axis=-1) if door[3] < door[4]: box = box + np.array([-1,0,1,0]) * thickness if door[4] > 0: box[1] = box[1] + thickness else: box[3] = box[3] - thickness else: box = box + np.array([0,-1,0,1]) * thickness if door[3] > 0: box[0] = box[0] + thickness else: box[2] = box[2] - thickness ax.fill(box[[0,0,2,2,0]], box[[1,3,3,1,1]], 'w', ec=cmap[16]) return ax