# Implementation of the module {block}. # Last edited on 2021-05-10 13:57:25 by jstolfi import block import path import move import move_parms import contact import job_parms import hacks import rn import pyx import sys from math import sqrt, floor, ceil, sin, cos, acos, pi, nan, inf class Block_IMP: # A {Block_IMP} object {bc} has a list {bc.OPHS} of {nch} one or more oriented # paths that are the choices. def __init__(self, OPHS ): self.OPHS = OPHS self.name = None # Fields for the heuristic: self.used = False self.seams = None self.cts = [] def from_paths(OPHS): assert type(OPHS) == list or type(OPHS) == tuple assert len(OPHS) > 0 bc = block.Block(tuple(OPHS)) return bc def nchoices(bc): assert isinstance(bc, block.Block) n = len(bc.OPHS) return n def choice(bc, ich): assert isinstance(bc, block.Block) n = len(bc.OPHS) assert ich >= 0 and ich < n och = bc.OPHS[ich] # Choice of the elements before reversal. return och def bbox(BCS): B = None for bc in BCS: B = rn.box_join(B, path.bbox(bc.OPHS)) assert B != None return B # ---------------------------------------------------------------------- def moves(bc): MVS = [] for ich in range(nchoices(bc)): oph = choice(bc,ich) for ich in range(path.nelems(oph)): omv = path.elem(oph,ich) mv, dr = move.unpack(omv) MVS.append(mv) MVS = list(set(MVS)) return MVS # ---------------------------------------------------------------------- def find_choice_with_move(bc, omv): for ich in range(nchoices(bc)): oph = choice(bc, ich) if path.find(oph, omv) != None: return ich return None #---------------------------------------------------------------------- def find_block_with_move(BCS, omv): nbc = len(BCS) for ich in range(nbc): bck = BCS[ich] if find_choice_with_move(bck, omv) != None: return ich return None def min_extime(bc): assert isinstance(bc, block.Block) n = len(bc.OPHS) mex = +inf for k in range(n): ophk = bc.OPHS[k] texk = path.extime(ophk) if texk < mex: mex = texk return mex def plot_to_files(fname, BCS, CLRS, wd_axes, matter): # Find the max number of choices {nch}: nch = 0 for bc in BCS: nch = max(nch, nchoices(bc)) # Get a plotting bounding box of all blocks: B = bbox(BCS) pbox = hacks.round_box(B, 1) szx, szy = rn.box_size(pbox) # Choose the vertical displacement {ystep} between sub-plots: ystep = 1 + szy c = pyx.canvas.canvas() pyx.unit.set(uscale=1.00, wscale=1.00, vscale=1.00) # Plot the sub-plot grids: for ich in range(nch): dpi = (0, ich*ystep) wd_grid = 0.002*szx hacks.plot_grid(c, None, wd_grid, dpi, pbox, -0.25, 1, 1) wd_frame = 0.003*szx hacks.plot_frame(c, None, wd_frame, dpi, pbox, 0.25) axes = True dots = True arrows = True plot_standard \ ( c, BCS, nch, None, ystep, CLRS, wd_axes=wd_axes, axes=axes, dots=dots, arrows=arrows, matter=matter ) hacks.write_plot(c, fname) return # ---------------------------------------------------------------------- def plot_standard(c, BCS, nch, dp, ystep, CLRS, wd_axes, axes, dots, arrows, matter): assert type(BCS) is list or type(BCS) is tuple nbc = len(BCS) if CLRS == None: CLRS = [ pyx.color.rgb(0.050, 0.800, 0.000), ] # Default trace color. else: assert type(CLRS) is list or type(CLRS) is tuple nclr = len(CLRS) assert nclr == 1 or nclr == nbc if dp == None: dp = (0,0) # Plot one choice from each block: for ich in range(nch): dpi = rn.add(dp, (0, ich*ystep)) if matter: # Plot the matter shadow of all plocks: for bc in BCS: plot_matter_shadow(c, bc, dpi) for k in range(nbc): sys.stderr.write("plotting choice %d of {BCS[%d]} at ( %.3f %.3f )\n" % (ich,k,dpi[0],dpi[1])) bc = BCS[k] clr = CLRS[k] if nclr == nbc else CLRS[0] plot_choice(c, bc, ich, dpi, clr, wd_axes, axes, dots, arrows) return # ---------------------------------------------------------------------- def plot_choice(c, bc, ich, dp, clr, wd_axes, axes, dots, arrows): nch = block.nchoices(bc) if ich < nch: sys.stderr.write(" plotting it\n") ophi = block.choice(bc, ich) path.plot_standard \ ( c, [ophi,], dp, None, [clr,], wd_axes=wd_axes, axes=axes, dots=dots, arrows=arrows, matter=False ) return # ---------------------------------------------------------------------- def plot_matter_shadow(c, bc, dp): rmatter = 1.13 cmatter = pyx.color.rgb(0.850, 0.800, 0.750) # Material footprint color. for ich in range(block.nchoices(bc)): oph = block.choice(bc, ich) path.plot_layer \ ( c, oph, dp, jmp=False, clr=cmatter, rwd=rmatter, wd=0, dashed=False, wd_dots=0, sz_arrows=0 ) return # ---------------------------------------------------------------------- def validate(bc): n = len(bc.OPHS) assert n >= 1 # sys.stderr.write("--- validating bc = %s n = %d ----------\n" % (str(bc), n)) # Validate the list of choices: for och in bc.OPHS: path.validate(och) ph, dr = path.unpack(och) # Typechecking. nmv = path.nelems(ph) assert nmv > 0 assert not move.is_jump(path.elem(ph,0)) assert not move.is_jump(path.elem(ph,nmv-1)) return # ---------------------------------------------------------------------- def get_name(bc): assert isinstance(bc, block.Block) name = bc.name if name == None: name = "B?" return name # ---------------------------------------------------------------------- def set_name(bc, name): assert type(name) is str bc.name = name return # ---------------------------------------------------------------------- def show(wr, bc, paths, ind, wna, wnc): wr.write(" "*ind) wr.write("%-*s" % (wna,get_name(bc))) nch = nchoices(bc) wr.write(" %*d" % (wnc, nch)) if paths: wr.write(" ") for ich in range(nch): oph = choice(bc, ich) phname = path.get_name(oph) if ich > 0: wr.write(",") wr.write(phname) return # ---------------------------------------------------------------------- def show_list(wr, BCS, paths): assert type(BCS) is list or type (BCS) is tuple nbc = len(BCS) if nbc == 0: return wna = 4 # Width of "name" column; min 4 because of the header. wnc = 1 # Width of "number of paths" column. for bc in BCS: wna = max(wna, len(get_name(bc))) wnc = max(wnc, len(str(nchoices(bc)))) wix = len(str(nbc-1)) # Num digits in index. wr.write("\n") # Write header: wr.write("%*s %-*s %*s paths \n" % (wix,"k",wna,"name",wnc,"n")) wr.write("%s %s %s --------------\n" % ("-"*wix,"-"*wna,"-"*wnc)) # Write blocks: for k in range(len(BCS)): bc = BCS[k] wr.write("%*d " % (wix,k)) show(wr, bc, paths, 0, wna, wnc) wr.write("\n") wr.write("\n") return # ----------------------------------------------------------------------