# Module to generate input datasets for the HotPath heuristic. # Last edited on 2021-02-19 14:30:26 by jstolfi import input_data_IMP # Each of the procedures below returns two results: a list {BS} of # zero or more {Block} objects, and a list {CS} of zero or more # {Contact} objects. These lists are suitable inputs to the HotPath # heuristic {hotpath.best_path}. # # Each block in {BS} has at least one alternative. Every alternative # of every block is path with at least one move that begins and ends # with a trace. The {Move} objects in each choice of each block are # all distinct, and no {Move} object is shared between choices of # distinct blocks. However, two or more different choices for a block # may share a {Move} object. In particular, if the block includes both # a path and its reversal, these two choices will share all their # {Move} objects. # # The move timing data, such as {move.extime(mv)} and # {contact.covtimes} will be based on the parameters # {parms['job_filling_speed']}, {parms['job_jump_speed']}, # {parms['extrusion_on_off_time']}, and {parms['acceleration']} def multi_raster_roads(nrd, nbc, nmv, wdf, parms): # Each block of the returned set {BS} will be either a single raster # line in its two possible directions, or a serpentine path of raster # lines linked by short vertical traces, in its four different orders # and directions. # # The main part of the input will be {nrd} "roads", side by side, each # consisting of a stack of {nbc} blocks with {nmv} raster lines each. # There will be also a horizontal raster line {H0} below and spanning # these roads, and another one {H1} at the top. # # All rasters will have nominal width {wdf}, and will be spaced # vertically by that amount. The width of each road and the gap # between the roads will be fixed multiples of {wdf}. # # There will be a contact between every pair or blocks, including {H0} # and {H1}, that are adjacent (have traces on successive scanlines and # overlapping {X} ranges). return input_data_IMP.multi_raster_rivers(nrd, nbc, nmv, wdf, parms) def two_roads_and_islands(nmv, nmg, nis, wdc, wdf, parms): # Returned list {BS} will have some "raster" blocks and some "island" # blocks. # # The raster blocks will form two parallel vertical roads, each # comprising {nmv} horizontal raster lines. There will be {nis} # islands arranged in a vertical group at the left of the left road, # between the two roads, and at the right of the right road, near the # middle. # # If {nmg} is 1, each raster line will be a separate block, with two # possible choices, corresponding to the two orientations. # # If {nmg} is greater than 1, only {nms} of the raster lines, in the # middle of the road, will be blocks by themseves, as above. The other # {nmv-nms} raster lines will be fused together into serpentine path # blocks of {nmg} rasters each. Each of these blocks will have 4 # choices: the two possible orders for the rasters (bottom to top, top # to bottom) and the two possible orientations for the bottom raster. # The number {nms} will be at least 1, and will be such that {nmv-nms} # is divisible by {2*nmg}. In particular, if {nmv} is less than # {4*nmg+1}, each raster will be a block by itself. # # All rasters will have width {wdf}, and will be spaced vertically by # that amount. The width of each road, the gap between the roads, and # the size and spacing of the islands will be fixed multiples of {wd}. # # An island block will have a single choice that is a small circular # filled contour. It starts and ends at nearly the same point, so # there is no point in adding the reversal. There will be {nis} # islands arranged in a vertical group at the left of the left road, # between the roads, and at the right of the right road. # # Island contours will be traced with nominal width {wdc}. The island # fillings will use traces of width {wdf}. # # There will be a contact between every pair of consecutive blocks in # each road. return input_data_IMP.two_roads_and_islands(nmv, nmg, nis, wdc, wdf, parms) # PLOTTING def plot(fname, BS, CS, o, wd): # Writes a set of EPS files showing the HotPath input dataset # {BS,CS,o}. Each EPS file shows choice {ip} of each block, for # {ip=0,1,...}, with contacts that are pertinent to that choice. Also # writes the equivalent "jpg", and "png" images. uses standard choices # for colors, decoration, etc. based on the trace width {wd}, # typically the width of solid fill raster lines. # # The files "{fname}_ip{ip}.{ext}" where {ip} is the choice number and {ext} # is "eps", "jpg", or "png". input_data_IMP.plot(fname, BS, CS, o, wd) def plot_choice(c, BS, ip, ctraces, waxes, CS, cconts, wconts): # Plots the blocks {BS} and the contacts {CS} on the canvas {c) # displaced by {dp}. Takes choice {ip} of each block. Only plots # contacts that have at least one side on those choices. If a block # does not have a choice {ip}, shows only the material shadow of # choice 0. input_data_IMP.plot_choice(c, BS, ip, ctraces, waxes, CS, cconts, wconts)