Example #1
0
def merge(opts, args, gui=None):
    writeGerberHeader = writeGerberHeader22degrees

    global GUI
    GUI = gui

    skipDisclaimer = 0

    for opt, arg in opts:
        if opt in ('--octagons', ):
            if arg == 'rotate':
                writeGerberHeader = writeGerberHeader0degrees
            elif arg == 'normal':
                writeGerberHeader = writeGerberHeader22degrees
            else:
                raise RuntimeError, 'Unknown octagon format'
        elif opt in ('--random-search', ):
            config.AutoSearchType = RANDOM_SEARCH
        elif opt in ('--full-search', ):
            config.AutoSearchType = EXHAUSTIVE_SEARCH
        elif opt in ('--rs-fsjobs', ):
            config.RandomSearchExhaustiveJobs = int(arg)
        elif opt in ('--search-timeout', ):
            config.SearchTimeout = int(arg)
        elif opt in ('--place-file', ):
            config.AutoSearchType = FROM_FILE
            config.PlacementFile = arg
        elif opt in ('--no-trim-gerber', ):
            config.TrimGerber = 0
        elif opt in ('--no-trim-excellon', ):
            config.TrimExcellon = 0
        elif opt in ('-s', '--skipdisclaimer'):
            skipDisclaimer = 1
        else:
            raise RuntimeError, "Unknown option: %s" % opt

    if len(args) > 2 or len(args) < 1:
        raise RuntimeError, 'Invalid number of arguments'

    if (skipDisclaimer == 0):
        disclaimer()

    # Load up the Jobs global dictionary, also filling out GAT, the
    # global aperture table and GAMT, the global aperture macro table.
    updateGUI("Reading job files...")
    config.parseConfigFile(args[0])

    # Display job properties
    for job in config.Jobs.values():
        print 'Job %s:' % job.name,
        if job.Repeat > 1:
            print '(%d instances)' % job.Repeat
        else:
            print
        print '  Extents: (%d,%d)-(%d,%d)' % (job.minx, job.miny, job.maxx,
                                              job.maxy)
        # add metric support (1/1000 mm vs. 1/100,000 inch)
        if config.Config['measurementunits'] == 'inch':
            print '  Size: %f" x %f"' % (job.width_in(), job.height_in())
        else:
            print '  Size: %5.3fmm x %5.3fmm' % (job.width_in(),
                                                 job.height_in())
        print

    # Trim drill locations and flash data to board extents
    if config.TrimExcellon:
        updateGUI("Trimming Excellon data...")
        print 'Trimming Excellon data to board outlines ...'
        for job in config.Jobs.values():
            job.trimExcellon()

    if config.TrimGerber:
        updateGUI("Trimming Gerber data...")
        print 'Trimming Gerber data to board outlines ...'
        for job in config.Jobs.values():
            job.trimGerber()

    # We start origin at (0.1", 0.1") just so we don't get numbers close to 0
    # which could trip up Excellon leading-0 elimination.
    # I don't want to change the origin. If this a code bug, then it should be fixed (SDD)
    OriginX = OriginY = 0  #0.1

    # Read the layout file and construct the nested list of jobs. If there
    # is no layout file, do auto-layout.
    updateGUI("Performing layout...")
    print 'Performing layout ...'
    if len(args) > 1:
        Layout = parselayout.parseLayoutFile(args[1])

        # Do the layout, updating offsets for each component job.
        X = OriginX + config.Config['leftmargin']
        Y = OriginY + config.Config['bottommargin']

        for row in Layout:
            row.setPosition(X, Y)
            Y += row.height_in() + config.Config['yspacing']

        # Construct a canonical placement from the layout
        Place = placement.Placement()
        Place.addFromLayout(Layout)

        del Layout

    elif config.AutoSearchType == FROM_FILE:
        Place = placement.Placement()
        Place.addFromFile(config.PlacementFile, config.Jobs)
    else:
        # Do an automatic layout based on our tiling algorithm.
        tile = tile_jobs(config.Jobs.values())

        Place = placement.Placement()
        Place.addFromTiling(tile, OriginX + config.Config['leftmargin'],
                            OriginY + config.Config['bottommargin'])

    (MaxXExtent, MaxYExtent) = Place.extents()
    MaxXExtent += config.Config['rightmargin']
    MaxYExtent += config.Config['topmargin']

    # Start printing out the Gerbers. In preparation for drawing cut marks
    # and crop marks, make sure we have an aperture to draw with. Use a 10mil line.
    # If we're doing a fabrication drawing, we'll need a 1mil line.
    OutputFiles = []

    try:
        fullname = config.MergeOutputFiles['placement']
    except KeyError:
        fullname = 'merged.placement.txt'
    Place.write(fullname)
    OutputFiles.append(fullname)

    # For cut lines
    AP = aptable.Aperture(aptable.Circle, 'D??', config.Config['cutlinewidth'])
    drawing_code_cut = aptable.findInApertureTable(AP)
    if drawing_code_cut is None:
        drawing_code_cut = aptable.addToApertureTable(AP)

    # For score lines
    AP = aptable.Aperture(aptable.Circle, 'D??',
                          config.Config['scoringlinewidth'])
    drawing_code_score = aptable.findInApertureTable(AP)
    if drawing_code_score is None:
        drawing_code_score = aptable.addToApertureTable(AP)

    # For crop marks
    AP = aptable.Aperture(aptable.Circle, 'D??',
                          config.Config['cropmarkwidth'])
    drawing_code_crop = aptable.findInApertureTable(AP)
    if drawing_code_crop is None:
        drawing_code_crop = aptable.addToApertureTable(AP)

    # For fiducials
    drawing_code_fiducial_copper = drawing_code_fiducial_soldermask = None
    if config.Config['fiducialpoints']:
        AP = aptable.Aperture(aptable.Circle, 'D??',
                              config.Config['fiducialcopperdiameter'])
        drawing_code_fiducial_copper = aptable.findInApertureTable(AP)
        if drawing_code_fiducial_copper is None:
            drawing_code_fiducial_copper = aptable.addToApertureTable(AP)
        AP = aptable.Aperture(aptable.Circle, 'D??',
                              config.Config['fiducialmaskdiameter'])
        drawing_code_fiducial_soldermask = aptable.findInApertureTable(AP)
        if drawing_code_fiducial_soldermask is None:
            drawing_code_fiducial_soldermask = aptable.addToApertureTable(AP)

    # For fabrication drawing.
    AP = aptable.Aperture(aptable.Circle, 'D??', 0.001)
    drawing_code1 = aptable.findInApertureTable(AP)
    if drawing_code1 is None:
        drawing_code1 = aptable.addToApertureTable(AP)

    updateGUI("Writing merged files...")
    print 'Writing merged output files ...'

    for layername in config.LayerList.keys():
        lname = layername
        if lname[0] == '*':
            lname = lname[1:]

        try:
            fullname = config.MergeOutputFiles[layername]
        except KeyError:
            fullname = 'merged.%s.ger' % lname
        OutputFiles.append(fullname)
        #print 'Writing %s ...' % fullname
        fid = file(fullname, 'wt')
        writeGerberHeader(fid)

        # Determine which apertures and macros are truly needed
        apUsedDict = {}
        apmUsedDict = {}
        for job in Place.jobs:
            apd, apmd = job.aperturesAndMacros(layername)
            apUsedDict.update(apd)
            apmUsedDict.update(apmd)

        # Increase aperature sizes to match minimum feature dimension
        if config.MinimumFeatureDimension.has_key(layername):

            print '  Thickening', lname, 'feature dimensions ...'

            # Fix each aperture used in this layer
            for ap in apUsedDict.keys():
                new = config.GAT[ap].getAdjusted(
                    config.MinimumFeatureDimension[layername])
                if not new:  ## current aperture size met minimum requirement
                    continue
                else:  ## new aperture was created
                    new_code = aptable.findOrAddAperture(
                        new
                    )  ## get name of existing aperture or create new one if needed
                    del apUsedDict[
                        ap]  ## the old aperture is no longer used in this layer
                    apUsedDict[
                        new_code] = None  ## the new aperture will be used in this layer

                    # Replace all references to the old aperture with the new one
                    for joblayout in Place.jobs:
                        job = joblayout.job  ##access job inside job layout
                        temp = []
                        if job.hasLayer(layername):
                            for x in job.commands[layername]:
                                if x == ap:
                                    temp.append(
                                        new_code
                                    )  ## replace old aperture with new one
                                else:
                                    temp.append(x)  ## keep old command
                            job.commands[layername] = temp

        if config.Config['cutlinelayers'] and (
                layername in config.Config['cutlinelayers']):
            apUsedDict[drawing_code_cut] = None

        if config.Config['scoringlinelayers'] and (
                layername in config.Config['scoringlinelayers']):
            apUsedDict[drawing_code_score] = None

        if config.Config['cropmarklayers'] and (
                layername in config.Config['cropmarklayers']):
            apUsedDict[drawing_code_crop] = None

        if config.Config['fiducialpoints']:
            if ((layername == '*toplayer') or (layername == '*bottomlayer')):
                apUsedDict[drawing_code_fiducial_copper] = None
            elif ((layername == '*topsoldermask')
                  or (layername == '*bottomsoldermask')):
                apUsedDict[drawing_code_fiducial_soldermask] = None

        # Write only necessary macro and aperture definitions to Gerber file
        writeApertureMacros(fid, apmUsedDict)
        writeApertures(fid, apUsedDict)

        #for row in Layout:
        #  row.writeGerber(fid, layername)

        #  # Do cut lines
        #  if config.Config['cutlinelayers'] and (layername in config.Config['cutlinelayers']):
        #    fid.write('%s*\n' % drawing_code_cut)    # Choose drawing aperture
        #    row.writeCutLines(fid, drawing_code_cut, OriginX, OriginY, MaxXExtent, MaxYExtent)

        # Finally, write actual flash data
        for job in Place.jobs:

            updateGUI("Writing merged output files...")
            job.writeGerber(fid, layername)

            if config.Config['cutlinelayers'] and (
                    layername in config.Config['cutlinelayers']):
                fid.write('%s*\n' %
                          drawing_code_cut)  # Choose drawing aperture
                #print "writing drawcode_cut: %s" % drawing_code_cut
                job.writeCutLines(fid, drawing_code_cut, OriginX, OriginY,
                                  MaxXExtent, MaxYExtent)

        # Draw the scoring lines
        if config.Config['scoringlinelayers'] and layername in config.Config[
                'scoringlinelayers']:
            fid.write('%s*\n' % drawing_code_score)  # Choose scoring aperture
            scoring.writeScoring(fid, Place, OriginX, OriginY, MaxXExtent,
                                 MaxYExtent)

        if config.Config['cropmarklayers']:
            if layername in config.Config['cropmarklayers']:
                writeCropMarks(fid, drawing_code_crop, OriginX, OriginY,
                               MaxXExtent, MaxYExtent)

        if config.Config['fiducialpoints']:
            # If we are generating fiducials along the score lines,
            #  and we have not yet done so, we need to generate those now, pass in None as the file
            #  to prevent it actually writing out scoring lines and just generate the fiducials
            if config.Config['fiducialpoints'] == 'scoring':
                scoring.writeScoring(None, Place, OriginX, OriginY, MaxXExtent,
                                     MaxYExtent)
            if ((layername == '*toplayer') or (layername == '*bottomlayer')):
                writeFiducials(fid, drawing_code_fiducial_copper, OriginX,
                               OriginY, MaxXExtent, MaxYExtent)
            elif ((layername == '*topsoldermask')
                  or (layername == '*bottomsoldermask')):
                writeFiducials(fid, drawing_code_fiducial_soldermask, OriginX,
                               OriginY, MaxXExtent, MaxYExtent)

        writeGerberFooter(fid)
        fid.close()

    # Write board outline layer if selected
    fullname = config.Config['outlinelayerfile']
    if fullname and fullname.lower() != "none":
        OutputFiles.append(fullname)
        #print 'Writing %s ...' % fullname
        fid = file(fullname, 'wt')
        writeGerberHeader(fid)

        # Write width-1 aperture to file
        # add metric support
        if config.Config['measurementunits'] == 'inch':
            AP = aptable.Aperture(aptable.Circle, 'D10', 0.001)
        else:
            AP = aptable.Aperture(aptable.Circle, 'D10',
                                  0.25)  # we'll use 0.25 mm - same as Diptrace
        AP.writeDef(fid)

        # Choose drawing aperture D10
        fid.write('D10*\n')

        # Draw the rectangle
        fid.write(
            'X%07dY%07dD02*\n' %
            (util.in2gerb(OriginX), util.in2gerb(OriginY)))  # Bottom-left
        fid.write(
            'X%07dY%07dD01*\n' %
            (util.in2gerb(OriginX), util.in2gerb(MaxYExtent)))  # Top-left
        fid.write(
            'X%07dY%07dD01*\n' %
            (util.in2gerb(MaxXExtent), util.in2gerb(MaxYExtent)))  # Top-right
        fid.write(
            'X%07dY%07dD01*\n' %
            (util.in2gerb(MaxXExtent), util.in2gerb(OriginY)))  # Bottom-right
        fid.write(
            'X%07dY%07dD01*\n' %
            (util.in2gerb(OriginX), util.in2gerb(OriginY)))  # Bottom-left

        writeGerberFooter(fid)
        fid.close()

    # Write scoring layer if selected
    fullname = config.Config['scoringfile']
    if fullname and fullname.lower() != "none":
        OutputFiles.append(fullname)
        #print 'Writing %s ...' % fullname
        fid = file(fullname, 'wt')
        writeGerberHeader(fid)

        # Write width-1 aperture to file
        AP = aptable.Aperture(aptable.Circle, 'D10', 0.001)
        AP.writeDef(fid)

        # Choose drawing aperture D10
        fid.write('D10*\n')

        # Draw the scoring lines
        scoring.writeScoring(fid, Place, OriginX, OriginY, MaxXExtent,
                             MaxYExtent)

        writeGerberFooter(fid)
        fid.close()

    # Get a list of all tools used by merging keys from each job's dictionary
    # of tools.
    if 0:
        Tools = {}
        for job in config.Jobs.values():
            for key in job.xcommands.keys():
                Tools[key] = 1

        Tools = Tools.keys()
        Tools.sort()
    else:
        toolNum = 0

        # First construct global mapping of diameters to tool numbers
        for job in config.Jobs.values():
            for tool, diam in job.xdiam.items():
                if config.GlobalToolRMap.has_key(diam):
                    continue

                toolNum += 1
                config.GlobalToolRMap[diam] = "T%02d" % toolNum

        # Cluster similar tool sizes to reduce number of drills
        if config.Config['drillclustertolerance'] > 0:
            config.GlobalToolRMap = drillcluster.cluster(
                config.GlobalToolRMap, config.Config['drillclustertolerance'])
            drillcluster.remap(Place.jobs, config.GlobalToolRMap.items())

        # Now construct mapping of tool numbers to diameters
        for diam, tool in config.GlobalToolRMap.items():
            config.GlobalToolMap[tool] = diam

        # Tools is just a list of tool names
        Tools = config.GlobalToolMap.keys()
        Tools.sort()

    fullname = config.Config['fabricationdrawingfile']
    if fullname and fullname.lower() != 'none':
        if len(Tools) > strokes.MaxNumDrillTools:
            raise RuntimeError, "Only %d different tool sizes supported for fabrication drawing." % strokes.MaxNumDrillTools

        OutputFiles.append(fullname)
        #print 'Writing %s ...' % fullname
        fid = file(fullname, 'wt')
        writeGerberHeader(fid)
        writeApertures(fid, {drawing_code1: None})
        fid.write('%s*\n' % drawing_code1)  # Choose drawing aperture

        fabdrawing.writeFabDrawing(fid, Place, Tools, OriginX, OriginY,
                                   MaxXExtent, MaxYExtent)

        writeGerberFooter(fid)
        fid.close()

    # Finally, print out the Excellon
    try:
        fullname = config.MergeOutputFiles['drills']
    except KeyError:
        fullname = 'merged.drills.xln'
    OutputFiles.append(fullname)
    #print 'Writing %s ...' % fullname
    fid = file(fullname, 'wt')

    writeExcellonHeader(fid)

    # Ensure each one of our tools is represented in the tool list specified
    # by the user.
    for tool in Tools:
        try:
            size = config.GlobalToolMap[tool]
        except:
            raise RuntimeError, "INTERNAL ERROR: Tool code %s not found in global tool map" % tool

        writeExcellonTool(fid, tool, size)

        #for row in Layout:
        #  row.writeExcellon(fid, size)
        for job in Place.jobs:
            job.writeExcellon(fid, size)

    writeExcellonFooter(fid)
    fid.close()

    updateGUI("Closing files...")

    # Compute stats
    jobarea = 0.0
    #for row in Layout:
    #  jobarea += row.jobarea()
    for job in Place.jobs:
        jobarea += job.jobarea()

    totalarea = ((MaxXExtent - OriginX) * (MaxYExtent - OriginY))

    ToolStats = {}
    drillhits = 0
    for tool in Tools:
        ToolStats[tool] = 0
        #for row in Layout:
        #  hits = row.drillhits(config.GlobalToolMap[tool])
        #  ToolStats[tool] += hits
        #  drillhits += hits
        for job in Place.jobs:
            hits = job.drillhits(config.GlobalToolMap[tool])
            ToolStats[tool] += hits
            drillhits += hits

    try:
        fullname = config.MergeOutputFiles['toollist']
    except KeyError:
        fullname = 'merged.toollist.drl'
    OutputFiles.append(fullname)
    #print 'Writing %s ...' % fullname
    fid = file(fullname, 'wt')

    print '-' * 50
    # add metric support (1/1000 mm vs. 1/100,000 inch)
    if config.Config['measurementunits'] == 'inch':
        print '     Job Size : %f" x %f"' % (MaxXExtent - OriginX,
                                             MaxYExtent - OriginY)
        print '     Job Area : %.2f sq. in.' % totalarea
    else:
        print '     Job Size : %.2fmm x %.2fmm' % (MaxXExtent - OriginX,
                                                   MaxYExtent - OriginY)
        print '     Job Area : %.0f mm2' % totalarea

    print '   Area Usage : %.1f%%' % (jobarea / totalarea * 100)
    print '   Drill hits : %d' % drillhits
    if config.Config['measurementunits'] == 'inch':
        print 'Drill density : %.1f hits/sq.in.' % (drillhits / totalarea)
    else:
        print 'Drill density : %.2f hits/cm2' % (100 * drillhits / totalarea)

    print '\nTool List:'
    smallestDrill = 999.9
    for tool in Tools:
        if ToolStats[tool]:
            if config.Config['measurementunits'] == 'inch':
                fid.write('%s %.4fin\n' % (tool, config.GlobalToolMap[tool]))
                print '  %s %.4f" %5d hits' % (
                    tool, config.GlobalToolMap[tool], ToolStats[tool])
            else:
                fid.write('%s %.4fmm\n' % (tool, config.GlobalToolMap[tool]))
                print '  %s %.4fmm %5d hits' % (
                    tool, config.GlobalToolMap[tool], ToolStats[tool])
            smallestDrill = min(smallestDrill, config.GlobalToolMap[tool])

    fid.close()
    if config.Config['measurementunits'] == 'inch':
        print "Smallest Tool: %.4fin" % smallestDrill
    else:
        print "Smallest Tool: %.4fmm" % smallestDrill

    print
    print 'Output Files :'
    for f in OutputFiles:
        print '  ', f

    if (MaxXExtent - OriginX) > config.Config['panelwidth'] or (
            MaxYExtent - OriginY) > config.Config['panelheight']:
        print '*' * 75
        print '*'
        # add metric support (1/1000 mm vs. 1/100,000 inch)
        if config.Config['measurementunits'] == 'inch':
            print '* ERROR: Merged job exceeds panel dimensions of %.1f"x%.1f"' % (
                config.Config['panelwidth'], config.Config['panelheight'])
        else:
            print '* ERROR: Merged job exceeds panel dimensions of %.1fmmx%.1fmm' % (
                config.Config['panelwidth'], config.Config['panelheight'])
        print '*'
        print '*' * 75
        sys.exit(1)

    # Done!
    return 0
Example #2
0
 def eventHandler(self, event, mouseX, mouseY, input_boxes, WoodnStoneBtnList, RiverbedSize, screen):
     if event.type == pygame.MOUSEBUTTONDOWN and self.buttonList[0].mouseOnButton(mouseX, mouseY) and event.button == LEFT:
         self.buttonList[0].setIsPressed(True)
         for btn in WoodnStoneBtnList.getButtonList():
             btn.setIsImgOnMouse(False)
             btn.setUnpressable(False)
                  
     if event.type == pygame.MOUSEBUTTONDOWN and self.buttonList[1].mouseOnButton(mouseX, mouseY) and event.button == LEFT:
         self.buttonList[1].setIsPressed(True)
         if len(WoodnStoneBtnList.getBufferArray())-1 > 0:
             WoodnStoneBtnList.setBufferArray(WoodnStoneBtnList.getBufferArray()[:-1])
             WoodnStoneBtnList.setBuffer()
             globals.placementVar.undo()
             
     
     #SAVE-BUTTON:
     if event.type == pygame.MOUSEBUTTONDOWN and self.buttonList[2].mouseOnButton(mouseX, mouseY) and event.button == LEFT:
         self.buttonList[2].setIsPressed(True) 
         imageToSave = pygame.Surface(RiverbedSize, pygame.SRCALPHA, 32)
         #CLEAR(imageToSave)
         imageToSave.blit(SCREEN, dest=(0,0), area=RIVERBED_POS+RIVERBED_SIZE)
         name = show_popup(POP_UP_SAVE_TEXT, (315, 245))
         if not name == None:
             #Regex matches only alphanumerical letters(no symbols except of "_")
             if not os.path.isdir("save"):
                 os.mkdir("save")
             if(re.match(r'\w+\..*', name)):
                 if(re.match(r'\w+\.bmp|\w+\.jpg|\w+\.png', name)):
                         pygame.image.save(imageToSave, "save/" + name)
                         show_warning("Speichern war erfolgreich.", \
                                      "", (410, 260), (0,0))  
                         self.buttonList[2].setIsPressed(False)                           
                     #Does the file already exist? 
                 elif os.path.isfile("save/" + name):
                     show_warning("Der Dateiname existiert bereits.", \
                                  "", (390, 260), (0,0)) 
                     self.buttonList[2].setIsPressed(False)
                     Log("Save warning:name already exists") 
                 else:
                     show_warning("Bitte nur \".bmp\", \".jpg\" und \".png\" verwenden.",\
                                  "Alle anderen Dateiendungen werden durch \".png\" ersetzt.",\
                                  (340, 260), (310, 275))
                     Log("Save warning:wrong ending")
                     name = re.sub(r'\..*', '', name)
                     if os.path.isfile("save/" + name + ".png"):
                         show_warning("Der Dateiname existiert bereits.", \
                                      "", (390, 260), (0,0))  
                     else:
                         pygame.image.save(imageToSave, "save/" + name + ".png")
                         show_warning("Speichern als .png-Datei war erfolgreich.", \
                                      "", (360, 260), (0,0))            
                     self.buttonList[2].setIsPressed(False)
             elif (re.match(r'.*\W.*', name)) or name == "":
                 #error handling
                 show_warning("Der Dateiname muss aus mindestens einem Zeichen, sowie", \
                              "nur aus Buchstaben, Nummern und Unterstrichen bestehen.",\
                               (311, 260), (310, 275))
                 self.buttonList[2].setIsPressed(False)
                 Log("Save warning:wrong Char")
             #Does the file already exist?            
             elif os.path.isfile("save/" + name + ".png"):
                 show_warning("Der Dateiname existiert bereits.", \
                              "", (390, 260), (0,0))  
                 self.buttonList[2].setIsPressed(False) 
                 Log("Save warning:name already exists")
             elif (re.match(r'\w+', name)):         
                 pygame.image.save(imageToSave, "save/" + name + ".png")
                 show_warning("Speichern war erfolgreich.", \
                              "", (410, 260), (0,0)) 
                 self.buttonList[2].setIsPressed(False) 
             else:
                 Log("unknown save error")
     #RESET-BUTTON
     if event.type == pygame.MOUSEBUTTONDOWN and self.buttonList[3].mouseOnButton(mouseX, mouseY) and event.button == LEFT:
         #open river bed selection
         self.buttonList[3].setIsPressed(True) 
         if show_security():
             globals.riverbedNumber = show_riverbed_selection()
             globals.placementVar = placement.Placement(COLORMAPS[globals.riverbedNumber], RIVERBED_POS)
             WoodnStoneBtnList.setBufferArray(WoodnStoneBtnList.getBufferArray()[:1])
             WoodnStoneBtnList.setBuffer()
             globals.placementVar.deleteItems()
             input_boxes.reset()
             self.buttonList[3].setIsPressed(False)
         else:
             self.buttonList[3].setIsPressed(False)
         
     for btn in self.buttonList:    
         if event.type == pygame.MOUSEBUTTONUP and event.button == LEFT:
             btn.setIsPressed(False)
Example #3
0
def main():
    
    pygame.init()
    pygame.font.init()
    pygame.display.set_caption(CAPTION)
    
    Log("Initializing pygame and font, setting caption")
    
    
    Log("Initializing inputboxes")
    input_boxes_list = [inputbox.EventInputBoxes( [] , SCREEN, font = ARIAL),
                        inputbox.EventInputBoxes( [(340,502)] , SCREEN, font = ARIAL),
                        inputbox.EventInputBoxes( [(91,459), (511,479)] , SCREEN, font = ARIAL),
                        inputbox.EventInputBoxes( [(178,394), (523,474), (36,468)] , SCREEN, font = ARIAL),
                        inputbox.EventInputBoxes( [(21,194),(88,404),(218,440),(489,441)] , SCREEN, font = ARIAL),
                        inputbox.EventInputBoxes( [(21,201),(21,441),(194,497),(401,518),(498,445)] , SCREEN, font = ARIAL)]
    
    Log("Loading Buttons")
    #define buttons for saving, undo
    file_buttons = button.FileBtns([((760, 2), PIC_TRASH_BTN_UP, PIC_TRASH_BTN_DOWN),\
                                    ((810, 2), PIC_UNDO_BTN_UP, PIC_UNDO_BTN_DOWN),\
                                    ((860, 2), PIC_SAVE_BTN_UP, PIC_SAVE_BTN_DOWN),\
                                    ((910, 2), PIC_NEW_BTN_UP, PIC_NEW_BTN_DOWN),])
    
    
    menu_buttons = button.WoodnStoneBtns([((732, 110), PIC_STONE_BUTTON1_UP, PIC_STONE_BUTTON1_DOWN, img.Img(0, 0, False, False, 0, PIC_STONE1, PIC_STONE1, PIC_STONE1)),\
                                          ((732, 188), PIC_STONE_BUTTON2_UP, PIC_STONE_BUTTON2_DOWN, img.Img(0, 0, False, False, 0, PIC_STONE2, PIC_STONE2, PIC_STONE2)),\
                                          ((732, 266), PIC_STONE_BUTTON3_UP, PIC_STONE_BUTTON3_DOWN, img.Img(0, 0, False, False, 0, PIC_STONE3, PIC_STONE3, PIC_STONE3)),\
                                          ((732, 344), PIC_STONE_BUTTON4_UP, PIC_STONE_BUTTON4_DOWN, img.Img(0, 0, False, False, 0, PIC_STONE4, PIC_STONE4, PIC_STONE4)),\
                                          ((732, 422), PIC_STONE_BUTTON5_UP, PIC_STONE_BUTTON5_DOWN, img.Img(0, 0, False, False, 0, PIC_STONE5, PIC_STONE5, PIC_STONE5)),\
                                          ((732, 500), PIC_STONE_BUTTON6_UP, PIC_STONE_BUTTON6_DOWN, img.Img(0, 0, False, False, 0, PIC_STONE6, PIC_STONE6, PIC_STONE6)),\
                                          ((865, 110), PIC_WOOD_BUTTON1_UP, PIC_WOOD_BUTTON1_DOWN, img.Img(0, 0, False, False, 0, PIC_WOOD1, PIC_WOOD1, PIC_WOOD1)),\
                                          ((865, 188), PIC_WOOD_BUTTON2_UP, PIC_WOOD_BUTTON2_DOWN, img.Img(0, 0, False, False, 0, PIC_WOOD2, PIC_WOOD2, PIC_WOOD2)),\
                                          ((865, 266), PIC_WOOD_BUTTON3_UP, PIC_WOOD_BUTTON3_DOWN, img.Img(0, 0, False, False, 0, PIC_WOOD3, PIC_WOOD3, PIC_WOOD3)),\
                                          ((865, 344), PIC_WOOD_BUTTON4_UP, PIC_WOOD_BUTTON4_DOWN, img.Img(0, 0, False, False, 0, PIC_WOOD4, PIC_WOOD4, PIC_WOOD4)),\
                                          ((865, 422), PIC_WOOD_BUTTON5_UP, PIC_WOOD_BUTTON5_DOWN, img.Img(0, 0, False, False, 0, PIC_WOOD5, PIC_WOOD5, PIC_WOOD5)),\
                                          ((865, 500), PIC_WOOD_BUTTON6_UP, PIC_WOOD_BUTTON6_DOWN, img.Img(0, 0, False, False, 0, PIC_WOOD6, PIC_WOOD6, PIC_WOOD6))]) 
                                          
     
    
    header = pygame.font.Font( FONT, 45).render( "Kawa - Fluss", True, (0,0,0) )
    stone_header = pygame.font.Font( FONT, 19).render( "Steine", True, (0,0,0) )
    wood_header = pygame.font.Font( FONT, 19).render( "Treibholz", True, (0,0,0) )
    stone_japan = pygame.font.Font( FONT, 12).render( "Iwa", True, (0,0,0) )
    wood_japan = pygame.font.Font( FONT, 12).render( "Ryuboku", True, (0,0,0) )
    underline = pygame.font.Font( FONT, 15)
    underline.set_underline(True)
    ustone = underline.render("Umweltfaktor", True, (0,0,0))
    uwood = underline.render("Ressource", True, (0,0,0))
    credits = pygame.font.Font( FONT, 12).render( ">CREDITS<", True, (0,0,0) )
    
    #open short explanation about the Kawa Model
    show_start_window(START_SIZE)
        
    #open river bed selection
    globals.riverbedNumber = show_riverbed_selection()
    
    #set keyboard repeat rate
    pygame.key.set_repeat(100,100)
     
    #start main loop
    globals.placementVar = placement.Placement(COLORMAPS[globals.riverbedNumber], RIVERBED_POS)

    Log("Enter main-loop...")
    while True:
        # auf 30 FPS beschraenken
        CLOCK.tick(FRAMERATE)
        CLEAR(BUFFER)
        #get mouse position
        mouseX, mouseY = pygame.mouse.get_pos()
        
        input_boxes = input_boxes_list[globals.riverbedNumber]
        SCREEN.fill((231, 232, 200))
        SCREEN.blit(RIVERBED_LIST[globals.riverbedNumber], RIVERBED_POS)   
        SCREEN.blit(header, (230,18))
        SCREEN.blit(stone_header, (761,60))
        SCREEN.blit(wood_header, (881,60))
        SCREEN.blit(stone_japan, (781,76))
        SCREEN.blit(wood_japan, (902,76))
        SCREEN.blit(ustone, (746,89))
        SCREEN.blit(uwood, (890,89))
        SCREEN.blit( credits, (0,SIZE[1]-credits.get_height()) )
        
        menu_buttons.blitter(SCREEN, mouseX, mouseY)
        file_buttons.blitter(SCREEN, mouseX, mouseY)
        input_boxes.updateBoxes()
            
        # Alle aufgelaufenen Events holen und abarbeiten.
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                if show_security():
                    sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                if isCreditsClicked(credits.get_rect(x=0,y=SIZE[1]-credits.get_height())): show_credits() 
                
            menu_buttons.eventHandler(event, mouseX, mouseY)
            file_buttons.eventHandler(event, mouseX, mouseY, input_boxes, menu_buttons, RIVERBED_SIZE, SCREEN)
            input_boxes.handleEvent(event)
    
    
        # Inhalt von screen anzeigen.
        pygame.display.update()
Example #4
0
def merge(opts, gui=None):
    global GUI
    GUI = gui

    if opts.octagons == 'rotate':
        writeGerberHeader = gerber.writeHeader0degrees
    else:
        writeGerberHeader = gerber.writeHeader22degrees

    if opts.search == 'random':
        config.AutoSearchType = RANDOM_SEARCH
    else:
        config.AutoSearchType = EXHAUSTIVE_SEARCH

    config.RandomSearchExhaustiveJobs = opts.rs_esjobs
    config.SearchTimeout = opts.search_timeout

    if opts.no_trim_gerber:
        config.TrimGerber = False
    if opts.no_trim_excellon:
        config.TrimExcellon = False

    config.text = opts.text
    config.text_size = opts.text_size
    config.text_stroke = opts.text_stroke
    config.text_x = opts.text_x
    config.text_y = opts.text_y

    # Load up the Jobs global dictionary, also filling out GAT, the
    # global aperture table and GAMT, the global aperture macro table.
    updateGUI("Reading job files...")
    config.parseConfigFile(opts.configfile)

    # Force all X and Y coordinates positive by adding absolute value of minimum X and Y
    for name, job in config.Jobs.items():
        min_x, min_y = job.mincoordinates()
        shift_x = shift_y = 0
        if min_x < 0:
            shift_x = abs(min_x)
        if min_y < 0:
            shift_y = abs(min_y)
        if (shift_x > 0) or (shift_y > 0):
            job.fixcoordinates(shift_x, shift_y)

    # Display job properties
    for job in config.Jobs.values():
        print("Job {:s}:".format(job.name))
        if job.Repeat > 1:
            print("({:d} instances)".format(job.Repeat))
        else:
            print()
        print("  Extents: ({:d},{:d})-({:d},{:d})".format(job.minx, job.miny, job.maxx, job.maxy))
        print("  Size: {:f}\" x {:f}\"".format(job.width_in(), job.height_in()))
        print()

    # Trim drill locations and flash data to board extents
    if config.TrimExcellon:
        updateGUI("Trimming Excellon data...")
        print("Trimming Excellon data to board outlines ...")
        for job in config.Jobs.values():
            job.trimExcellon()

    if config.TrimGerber:
        updateGUI("Trimming Gerber data...")
        print("Trimming Gerber data to board outlines ...")
        for job in config.Jobs.values():
            job.trimGerber()

    # We start origin at (0.1", 0.1") just so we don't get numbers close to 0
    # which could trip up Excellon leading-0 elimination.
    OriginX = OriginY = 0.1

    # Read the layout file and construct the nested list of jobs. If there
    # is no layout file, do auto-layout.
    updateGUI("Performing layout...")
    print("Performing layout ...")
    if opts.layoutfile:
        # Construct a canonical placement from the manual layout (relative or absolute)
        Place = placement.Placement()
        Place.addFromFile(opts.layoutfile, OriginX + config.Config['leftmargin'], OriginY + config.Config['bottommargin'])
    else:
        # Do an automatic layout based on our tiling algorithm.
        tile = tile_jobs(config.Jobs.values())

        Place = placement.Placement()
        Place.addFromTiling(tile, OriginX + config.Config['leftmargin'], OriginY + config.Config['bottommargin'])

    (MaxXExtent, MaxYExtent) = Place.extents()
    MaxXExtent += config.Config['rightmargin']
    MaxYExtent += config.Config['topmargin']

    # Start printing out the Gerbers. In preparation for drawing cut marks
    # and crop marks, make sure we have an aperture to draw with. Use a 10mil line.
    # If we're doing a fabrication drawing, we'll need a 1mil line.
    OutputFiles = []

    try:
        fullname = config.MergeOutputFiles['placement']
    except KeyError:
        fullname = 'merged.placement.xml'
    Place.write(fullname)
    OutputFiles.append(fullname)

    # For cut lines
    AP = aptable.Aperture(aptable.Circle, 'D??', config.Config['cutlinewidth'])
    drawing_code_cut = aptable.findInApertureTable(AP, config.GAT)
    if drawing_code_cut is None:
        drawing_code_cut = aptable.addToApertureTable(AP, config.GAT)

    # For crop marks
    AP = aptable.Aperture(aptable.Circle, 'D??', config.Config['cropmarkwidth'])
    drawing_code_crop = aptable.findInApertureTable(AP, config.GAT)
    if drawing_code_crop is None:
        drawing_code_crop = aptable.addToApertureTable(AP, config.GAT)

    # For fiducials
    drawing_code_fiducial_copper = drawing_code_fiducial_soldermask = None
    if config.Config['fiducialpoints']:
        AP = aptable.Aperture(aptable.Circle, 'D??', config.Config['fiducialcopperdiameter'])
        drawing_code_fiducial_copper = aptable.findInApertureTable(AP, config.GAT)
        if drawing_code_fiducial_copper is None:
            drawing_code_fiducial_copper = aptable.addToApertureTable(AP, config.GAT)
        AP = aptable.Aperture(aptable.Circle, 'D??', config.Config['fiducialmaskdiameter'])
        drawing_code_fiducial_soldermask = aptable.findInApertureTable(AP, config.GAT)
        if drawing_code_fiducial_soldermask is None:
            drawing_code_fiducial_soldermask = aptable.addToApertureTable(AP, config.GAT)

    if config.text:
        text_size_ratio = 0.5  # proportion of Y spacing to use for text (much of this is taken up by, e.g., cutlines)
        if not config.text_size:
            print("Computing text size based on Y spacing...")
        text_size = config.text_size if config.text_size else (config.Config['yspacing'] * 1000.0) * text_size_ratio
        if text_size < config.min_text_size:
            print("Warning: Text size ({0} mils) less than minimum ({1} mils), using minimum.".format(text_size, config.min_text_size))
        text_size = max(text_size, config.min_text_size)
        print("Using text size: {0} mils".format(text_size))

        # by default, set stroke proportional to the size based on the ratio of the minimum stroke to the minimum size
        if not config.text_stroke:
            print("Computing text stroke based on text size...")
        text_stroke = config.text_stroke if config.text_stroke else int((text_size / config.min_text_size) * config.min_text_stroke)
        if text_stroke < config.min_text_stroke:
            print("Warning: Text stroke ({0} mils) less than minimum ({1} mils), using minimum.".format(text_stroke, config.min_text_stroke))
        text_stroke = max(text_stroke, config.min_text_stroke)
        print("Using text stroke: {0} mils".format(text_stroke))

        AP = aptable.Aperture(aptable.Circle, 'D??', text_stroke / 1000.0)
        drawing_code_text = aptable.findInApertureTable(AP, config.GAT)
        if drawing_code_text is None:
            drawing_code_text = aptable.addToApertureTable(AP, config.GAT)

    # For fabrication drawing.
    AP = aptable.Aperture(aptable.Circle, 'D??', 0.001)
    drawing_code1 = aptable.findInApertureTable(AP, config.GAT)
    if drawing_code1 is None:
        drawing_code1 = aptable.addToApertureTable(AP, config.GAT)

    updateGUI("Writing merged files...")
    print("Writing merged output files ...")

    for layername in config.LayerList.keys():
        lname = layername
        if lname[0] == '*':
            lname = lname[1:]

        try:
            fullname = config.MergeOutputFiles[layername]
        except KeyError:
            fullname = "merged.{:s}.ger".format(lname)
        OutputFiles.append(fullname)
        fid = open(fullname, 'wt')
        writeGerberHeader(fid)

        # Determine which apertures and macros are truly needed
        apUsedDict = {}
        apmUsedDict = {}
        for job in Place.jobs:
            apd, apmd = job.aperturesAndMacros(layername)
            apUsedDict.update(apd)
            apmUsedDict.update(apmd)

        # Increase aperature sizes to match minimum feature dimension
        if layername in config.MinimumFeatureDimension:

            print("  Thickening", lname, "feature dimensions ...")

            # Fix each aperture used in this layer
            for ap in list(apUsedDict.keys()):
                new = config.GAT[ap].getAdjusted(config.MinimumFeatureDimension[layername])
                if not new:  # current aperture size met minimum requirement
                    continue
                else:       # new aperture was created
                    new_code = aptable.findOrAddAperture(new, config.GAT)  # get name of existing aperture or create new one if needed
                    del apUsedDict[ap]                         # the old aperture is no longer used in this layer
                    apUsedDict[new_code] = None                # the new aperture will be used in this layer

                    # Replace all references to the old aperture with the new one
                    for joblayout in Place.jobs:
                        job = joblayout.job  # access job inside job layout
                        temp = []
                        if job.hasLayer(layername):
                            for x in job.commands[layername]:
                                if x == ap:
                                    temp.append(new_code)  # replace old aperture with new one
                                else:
                                    temp.append(x)         # keep old command
                            job.commands[layername] = temp

        if config.Config['cutlinelayers'] and (layername in config.Config['cutlinelayers']):
            apUsedDict[drawing_code_cut] = None

        if config.Config['cropmarklayers'] and (layername in config.Config['cropmarklayers']):
            apUsedDict[drawing_code_crop] = None

        if config.Config['fiducialpoints']:
            if ((layername == '*toplayer') or (layername == '*bottomlayer')):
                apUsedDict[drawing_code_fiducial_copper] = None
            elif ((layername == '*topsoldermask') or (layername == '*bottomsoldermask')):
                apUsedDict[drawing_code_fiducial_soldermask] = None

        if config.text:
            apUsedDict[drawing_code_text] = None

        # Write only necessary macro and aperture definitions to Gerber file
        gerber.writeApertureMacros(fid, apmUsedDict)
        gerber.writeApertures(fid, apUsedDict)

        # Finally, write actual flash data
        for job in Place.jobs:

            updateGUI("Writing merged output files...")
            job.writeGerber(fid, layername)

            if config.Config['cutlinelayers'] and (layername in config.Config['cutlinelayers']):
                fid.write("{:s}*\n".format(drawing_code_cut))    # Choose drawing aperture
                job.writeCutLines(fid, drawing_code_cut, OriginX, OriginY, MaxXExtent, MaxYExtent)

        if config.Config['cropmarklayers']:
            if layername in config.Config['cropmarklayers']:
                gerber.writeCropMarks(fid, drawing_code_crop, OriginX, OriginY, MaxXExtent, MaxYExtent)

        if config.Config['fiducialpoints']:
            if ((layername == '*toplayer') or (layername == '*bottomlayer')):
                gerber.writeFiducials(fid, drawing_code_fiducial_copper, OriginX, OriginY, MaxXExtent, MaxYExtent)
            elif ((layername == '*topsoldermask') or (layername == '*bottomsoldermask')):
                gerber.writeFiducials(fid, drawing_code_fiducial_soldermask, OriginX, OriginY, MaxXExtent, MaxYExtent)
        if config.Config['outlinelayers'] and (layername in config.Config['outlinelayers']):
            gerber.writeOutline(fid, OriginX, OriginY, MaxXExtent, MaxYExtent)

        if config.text:
            Y += row.height_in() + config.Config['yspacing']
            x = config.text_x if config.text_x else util.in2mil(OriginX + config.Config['leftmargin']) + 100  # convert inches to mils 100 is extra margin
            y_offset = ((config.Config['yspacing'] * 1000.0) - text_size) / 2.0
            y = config.text_y if config.text_y else util.in2mil(OriginY + config.Config['bottommargin'] + Place.jobs[0].height_in()) + y_offset  # convert inches to mils
            fid.write("{:s}*\n".format(drawing_code_text))    # Choose drawing aperture
            makestroke.writeString(fid, config.text, int(util.mil2gerb(x)), int(util.mil2gerb(y)), 0, int(text_size))
        gerber.writeFooter(fid)

        fid.close()

    # Write board outline layer if selected
    fullname = config.Config['outlinelayerfile']
    if fullname and fullname.lower() != "none":
        OutputFiles.append(fullname)
        fid = open(fullname, 'wt')
        writeGerberHeader(fid)

        gerber.writeOutline(fid, OriginX, OriginY, MaxXExtent, MaxYExtent)

        gerber.writeFooter(fid)
        fid.close()

    # Write scoring layer if selected
    fullname = config.Config['scoringfile']
    if fullname and fullname.lower() != "none":
        OutputFiles.append(fullname)
        fid = open(fullname, 'wt')
        writeGerberHeader(fid)

        # Write width-1 aperture to file
        AP = aptable.Aperture(aptable.Circle, 'D10', 0.001)
        AP.writeDef(fid)

        # Choose drawing aperture D10
        gerber.writeCurrentAperture(fid, 10)

        # Draw the scoring lines
        scoring.writeScoring(fid, Place, OriginX, OriginY, MaxXExtent, MaxYExtent, config.Config['xspacing'], config.Config['yspacing'])

        gerber.writeFooter(fid)
        fid.close()

    # Get a list of all tools used by merging keys from each job's dictionary
    # of tools.
    # Grab all tool diameters and sort them.
    allToolDiam = []
    for job in config.Jobs.values():
        for tool, diam in job.xdiam.items():
            if diam in config.GlobalToolRMap:
                continue

            allToolDiam.append(diam)
    allToolDiam.sort()
    
    # Then construct global mapping of diameters to tool numbers
    toolNum = 1
    for d in allToolDiam:
        config.GlobalToolRMap[d] = "T{:02d}".format(toolNum)
        toolNum += 1

    # Cluster similar tool sizes to reduce number of drills
    if config.Config['drillclustertolerance'] > 0:
        config.GlobalToolRMap = drillcluster.cluster(config.GlobalToolRMap, config.Config['drillclustertolerance'])
        drillcluster.remap(Place.jobs, list(config.GlobalToolRMap.items()))

    # Now construct mapping of tool numbers to diameters
    for diam, tool in config.GlobalToolRMap.items():
        config.GlobalToolMap[tool] = diam

    # Tools is just a list of tool names
    Tools = list(config.GlobalToolMap.keys())
    Tools.sort()

    fullname = config.Config['fabricationdrawingfile']
    if fullname and fullname.lower() != 'none':
        if len(Tools) > strokes.MaxNumDrillTools:
            raise RuntimeError("Only {:d} different tool sizes supported for fabrication drawing.".format(strokes.MaxNumDrillTools))

        OutputFiles.append(fullname)
        fid = open(fullname, 'wt')
        writeGerberHeader(fid)
        gerber.writeApertures(fid, {drawing_code1: None})
        fid.write("{:s}*\n".format(drawing_code1))    # Choose drawing aperture

        fabdrawing.writeFabDrawing(fid, Place, Tools, OriginX, OriginY, MaxXExtent, MaxYExtent)

        gerber.writeFooter(fid)
        fid.close()

    # Finally, print out the Excellon
    try:
        fullname = config.MergeOutputFiles['drills']
    except KeyError:
        fullname = "merged.drills.xln"
    OutputFiles.append(fullname)
    fid = open(fullname, 'wt')

    excellon.writeheader(fid, [(x, config.GlobalToolMap[x]) for x in Tools], units='in')

    # Ensure each one of our tools is represented in the tool list specified
    # by the user.
    for tool in Tools:
        try:
            size = config.GlobalToolMap[tool]
        except:
            raise RuntimeError("INTERNAL ERROR: Tool code {:s} not found in global tool map".format(tool))

        # Write the tool name then all of the positions where it will be drilled.
        excellon.writetoolname(fid, tool)
        for job in Place.jobs:
            job.writeExcellon(fid, size)

    excellon.writefooter(fid)
    fid.close()

    updateGUI("Closing files...")

    # Compute stats
    jobarea = 0.0
    for job in Place.jobs:
        jobarea += job.jobarea()

    totalarea = ((MaxXExtent - OriginX) * (MaxYExtent - OriginY))

    ToolStats = {}
    drillhits = 0
    for tool in Tools:
        ToolStats[tool] = 0
        for job in Place.jobs:
            hits = job.drillhits(config.GlobalToolMap[tool])
            ToolStats[tool] += hits
            drillhits += hits

    try:
        fullname = config.MergeOutputFiles['toollist']
    except KeyError:
        fullname = "merged.toollist.drl"
    OutputFiles.append(fullname)
    fid = open(fullname, 'wt')

    print('-' * 50)
    print("     Job Size : {:f}\" x {:f}\"".format(MaxXExtent - OriginX, MaxYExtent - OriginY))
    print("     Job Area : {:.2f} sq. in.".format(totalarea))
    print("   Area Usage : {:.1f}%".format(jobarea / totalarea * 100))
    print("   Drill hits : {:d}".format(drillhits))
    print("Drill density : {:.1f} hits/sq.in.".format(drillhits / totalarea))

    print("\nTool List:")
    smallestDrill = 999.9
    for tool in Tools:
        if ToolStats[tool]:
            fid.write("{:s} {:.4f}in\n".format(tool, config.GlobalToolMap[tool]))
            print("  {:s} {:.4f}\" {:5d} hits".format(tool, config.GlobalToolMap[tool], ToolStats[tool]))
            smallestDrill = min(smallestDrill, config.GlobalToolMap[tool])

    fid.close()
    print("Smallest Tool: {:.4f}in".format(smallestDrill))

    print()
    print("Output Files :")
    for f in OutputFiles:
        print("  ", f)

    if (MaxXExtent - OriginX) > config.Config['panelwidth'] or (MaxYExtent - OriginY) > config.Config['panelheight']:
        print('*' * 75)
        print("*")
        print("* ERROR: Merged job {:.3f}\"x{:.3f}\" exceeds panel dimensions of {:.3f}\"x{:.3f}\"".format(MaxXExtent - OriginX, MaxYExtent - OriginY, config.Config['panelwidth'], config.Config['panelheight']))
        print("*")
        print('*' * 75)
        sys.exit(1)

    # Done!
    return 0
Example #5
0
    # Read the layout file and construct the nested list of jobs. If there
    # is no layout file, do auto-layout.
    print 'Performing layout ...'
    if len(args) > 1:
        Layout = parselayout.parseLayoutFile(args[1])

        # Do the layout, updating offsets for each component job.
        X = OriginX + config.Config['leftmargin']
        Y = OriginY + config.Config['bottommargin']

        for row in Layout:
            row.setPosition(X, Y)
            Y += row.height_in() + config.Config['yspacing']

        # Construct a canonical placement from the layout
        Place = placement.Placement()
        Place.addFromLayout(Layout)

        del Layout

    elif config.AutoSearchType == FROM_FILE:
        Place = placement.Placement()
        Place.addFromFile(config.PlacementFile, config.Jobs)
    else:
        # Do an automatic layout based on our tiling algorithm.
        tile = tile_jobs(config.Jobs.values())

        Place = placement.Placement()
        Place.addFromTiling(tile, OriginX + config.Config['leftmargin'],
                            OriginY + config.Config['bottommargin'])
Example #6
0
    def prop(self, lam):
        """ Like propagate, but returns a Placement object"""

        import placement
        return placement.Placement(np.squeeze(self.propagate(lam)),
                                   np.squeeze(self.d))