• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Allegro X Scripting - Skill
  3. SKILL program to save user colors

Stats

  • State Suggested Answer
  • Replies 3
  • Answers 1
  • Subscribers 18
  • Views 6367
  • Members are here 0
More Content

SKILL program to save user colors

soll
soll over 3 years ago

Hello :)

I have written a SKILL program that save/load the colors of a BRD. It saves both the color palette and the colors associated with each subclass into a file, that can be loaded to another BRD (or the same).

It mostly works :p On some (rather) rare occasions, the SaveColors() function will skip some subclasses, or mess their name, and I have no idea why. But most of the time, it works. It has been written with Cadence 17.2, but should work on any version.

Sometime, after loading a color file, I get this error (SPMHDB-197): Subclass color index out of range. If anybody know what it exactly means, I am interested. If someone know were I could find a list of all the error codes and their meanings, I would be very interested too !

If you have any idea on how to make this program better or if you spot some grammatical/spelling mistakes, don't hesitate to tell !
If someone knows how to save the global transparency and shapes transparency of the Display tab (color dialog window), I think it would be a nice addition.

REMINDER : always double save you BRD before executing some SKILL code from and internet stranger :p I didn't had any problem with this program, but I don't know if it works the same on my setup and on yours. It probably does.

Here is the code :

; SaveColors() : save subclasses colors in a .colors file
; LoadColors() : load subclasses colors from a file
; skill "load SaveColors.il"

axlCmdRegister("savecolors" 'SaveColors ?cmdType "general")
axlCmdRegister("loadcolors" 'LoadColors ?cmdType "general")

procedure( SaveColors()
let((colorFileName colorFilePort subclass)
    ; color file creation
    colorFileName = axlDMFileBrowse(nil t ?defaultName strcat("./" axlCurrentDesign() "-" getLogin() ".colors") ?title "Save Colors As")
    colorFilePort = outfile(colorFileName)
    fprintf(colorFilePort ";:;:;:;:;:;:;:;:;:;:;:;:;:;:;:\n\n")
    fprintf(colorFilePort "    Color file       : %s\n" colorFileName)
    fprintf(colorFilePort "    User             : %s\n" getLogin())
    fprintf(colorFilePort "    Drawing          : %s.brd\n" axlCurrentDesign())
    fprintf(colorFilePort "    Software version : %s\n" getVersion())
    fprintf(colorFilePort "    Date/Time        : %s\n\n" getCurrentTime())
    fprintf(colorFilePort "---\n")
    
    ; get color palette
    paletteList = axlColorGet('all)
    foreach(color paletteList
        fprintf(colorFilePort "%d~%d~%d\n" nth(0 color) nth(1 color) nth(2 color))
    ) ;foreach
    
    fprintf(colorFilePort "???\n")
    
    ; get colors for each subclass
    foreach(ClassName axlGetParam("paramLayerGroup")->groupMembers
        foreach(SubclassName (axlGetParam(strcat("paramLayerGroup:" ClassName))->groupMembers)
            subclass = axlLayerGet(strcat(ClassName "/" SubclassName))
            fprintf(colorFilePort "%s/%s~%d~%d\n" ClassName SubclassName subclass->color subclass->pattern)
        ) ;foreach
    ) ;foreach
    
    fprintf(colorFilePort "!!!\n")
    close(colorFilePort)
    printf("Colors saved under %s." colorFileName)
)) ;let,procedure


procedure( LoadColors()
prog((colorFileName colorFilePort currentLine parsedLine colorPalette)
    colorFileName = axlDMFileBrowse(nil nil ?title "Load Colors")
    colorFilePort = infile(colorFileName)
    currentLine = ""
    
    ; checks that the selected file is a color file
    if(gets(currentLine colorFilePort) != ";:;:;:;:;:;:;:;:;:;:;:;:;:;:;:\n"
        then
            ;println(currentLine)
            axlUIConfirm("Le fichier choisi n'est pas compatible\n" 'error)
            return()
    ) ;if
    
    ; get to the color list
    while(currentLine != "---\n"
        gets(currentLine colorFilePort)
    ) ;while
    
    ; set the colors palette
    while(currentLine != "???\n"
        gets(currentLine colorFilePort)
        unless( currentLine == "???\n"
            parsedLine = parseString(currentLine "~")
            parsedLine = list(atoi(nth(0 parsedLine)), atoi(nth(1 parsedLine)), atoi(nth(2 parsedLine)))
            colorPalette = cons(parsedLine colorPalette)
        ) ;unless
    ) ;while
    colorPalette = reverse(colorPalette)
    axlColorSet('all colorPalette)    
    
    ; set the subclasses colors
    while(currentLine != "!!!\n"
        gets(currentLine colorFilePort)
        parsedLine = parseString(currentLine "~")        
        subclass = axlLayerGet(nth(0 parsedLine))
        if(subclass != nil
            then
                subclass->color = atoi(nth(1 parsedLine))
                subclass->pattern = atoi(nth(2 parsedLine))
                axlLayerSet(subclass)
        ) ;if
    ) ;while
    
    ; update display
    axlVisibleUpdate(t)
    printf("Color file loaded succesfully (I guess).")
    
    close(colorFilePort)
)) ;let,procedure

  • Cancel
  • Sign in to reply
  • DavidJHutchins
    0 DavidJHutchins over 3 years ago

    attached is some skill code I wrote ~20 ago, I haven't heard of any issues with it recently...

    procedure((XXX_write_colors \@optional FileName)
    prog((fptr OutputName Classes Class SubClasses Layer lineCnt visible)
    if( FileName then
    (OutputName = strcat(simplifyFilename(".") "/" FileName))
    (OutputName = FileName)
    else
    (OutputName = "colors.alc")
    (OutputName = strcat(simplifyFilename(".") "/colors.alc"))
    )
    (lineCnt = 0)
    (visible = 0)
    if(( stringp(OutputName) && (isFile(OutputName) == t)) then
    unless(deleteFile(OutputName)
    (axlMsgPut "ERROR: could not remove existing file %s" OutputName)
    return()
    )
    )
    if((fptr = outfile(OutputName)) then
    (Classes = ((axlGetParam "paramLayerGroup")->groupMembers))
    (axlMsgPut "building class/subclass layer list.")
    (Layer = nil)
    foreach(class Classes
    (Class = (axlGetParam sprintf(nil "paramLayerGroup:%s" class)))
    (SubClasses = Class->groupMembers)
    foreach(SubClass SubClasses
    (Layer = (axlGetParam sprintf(nil "paramLayerGroup:%s/paramLayer:%s" class SubClass)))
    if((Layer->visible) then
    (visible = 1)
    else
    (visible = 0)
    )
    fprintf(fptr "%s/%s/%d/%d\n" class SubClass (Layer->color) visible)
    lineCnt++
    )
    )
    ;; phase 2 - write net colors to file...
    foreach(net ((axlDBGetDesign)->nets)
    when(axlIsCustomColored(net)
    fprintf(fptr "(axlCustomColorObject %s %d)\n" net->name axlIsCustomColored(net))
    )
    )
    close(fptr)
    (axlMsgPut "%d layers written to %s" lineCnt OutputName)
    else
    (axlMsgPut "ERROR: could not open output file %s" OutputName)
    return()
    )
    )
    )
    procedure((XXX_read_colors \@optional (FileName "colors.alc"))
    ;;"read the Allegro Layer Colors ( alc ) file & set the layer attributes"
    prog((inport lineCnt setCnt addCnt netCnt DataLine
    TempLine DataList Class SubClass Layer Net TextString color visible)
    if(( stringp(FileName) && (isFile(FileName) == t)) then
    (inport = infile(FileName))
    (lineCnt = 0)
    (setCnt = 0)
    (addCnt = 0)
    (netCnt = 0)
    when(inport
    while(gets(DataLine inport)
    lineCnt++
    (TempLine = parseString(DataLine "\n\r"))
    if(nindex(car(TempLine) "(axlCustomColorObject") then
    (SubClass = nil)
    (DataList = parseString(car(TempLine)))
    axlClearSelSet()
    (Net = axlDBFindByName('net cadr(DataList)))
    when(Net
    (axlCustomColorObject Net atoi(caddr(DataList)))
    (netCnt++)
    )
    axlClearSelSet()
    else
    (DataList = parseString(car(TempLine) '\/))
    if((length(DataList) > 0) then
    if(stringp(car(DataList)) then
    (Class = car(DataList))
    else
    (Class = "ETCH")
    )
    if(stringp(cadr(DataList)) then
    (SubClass = cadr(DataList))
    )
    if(stringp(caddr(DataList)) then
    (color = atoi(caddr(DataList)))
    else
    (color = 0)
    )
    if(stringp(cadddr(DataList)) then
    (visible = atoi(cadddr(DataList)))
    else
    (visible = 0)
    )
    )
    when(SubClass
    (Layer = (axlGetParam sprintf(TextString "paramLayerGroup:%s/paramLayer:%s" Class SubClass)))
    if((!Layer && !(Class == "ETCH") && !(Class == "ANTI ETCH") && !(Class == "PIN") && !(Class == "VIA CLASS") && !(Class == "DRC ERROR CLASS") && !(Class == "ROUTE KEEPOUT") && !(Class == "VIA KEEPOUT")) then
    addCnt++
    (axlLayerCreateNonConductor sprintf(TextString "%s/%s" Class SubClass))
    (Layer = (axlGetParam sprintf(TextString "paramLayerGroup:%s/paramLayer:%s" Class SubClass)))
    )
    if(Layer then
    setCnt++
    (Layer->color = color)
    if((visible == 1) then
    (Layer->visible = t)
    else
    (Layer->visible = nil)
    )
    (axlSetParam Layer)
    )
    )
    )
    )
    )
    close(inport)
    (axlMsgPut "%d lines processed, %d layers set, %d layers added,%d nets set" lineCnt setCnt addCnt netCnt)
    (axlUIWRedraw nil)
    )
    )
    )
    ;;
    procedure(XXX_export_colors_Callback(form)
    ;;"process the user input"
    let(()
    case((form->curField)
    ("execute"
    axlFormClose( form)
    axlCancelEnterFun()
    if(( stringp(XXX_FormFile) && (isFile(XXX_FormFile) == t)) then
    deleteFile(XXX_FormFile)
    )
    XXX_write_colors( XXX_IO_FileName )
    t
    )
    ("cancel"
    axlFormClose( form)
    axlCancelEnterFun()
    if(( stringp(XXX_FormFile) && (isFile(XXX_FormFile) == t)) then
    deleteFile(XXX_FormFile)
    )
    nil
    )
    ("filename"
    (XXX_IO_FileName = (form->curValue))
    t
    )
    )
    )
    )
    procedure(XXX_export_colors_BuildForm( XXX_FormFileArg )
    ;;"build the form file"
    let((FORMFILE)
    if(( stringp(XXX_FormFileArg) && (isFile(XXX_FormFileArg) == t)) then
    deleteFile(XXX_FormFileArg)
    )
    (FORMFILE = outfile(XXX_FormFileArg))
    fprintf(FORMFILE "FILE_TYPE=FORM_DEFN VERSION=2\n")
    fprintf(FORMFILE "FORM\n")
    fprintf(FORMFILE "FIXED\n")
    fprintf(FORMFILE "PORT 50 10\n")
    fprintf(FORMFILE "HEADER \"Layer Colors\"\n")
    fprintf(FORMFILE "\n")
    fprintf(FORMFILE "TILE\n")
    fprintf(FORMFILE "\n")
    fprintf(FORMFILE "TEXT \"Output File: ( recommend a file extension .alc )\"\n")
    fprintf(FORMFILE "TLOC 1 1\n")
    fprintf(FORMFILE "ENDTEXT\n")
    fprintf(FORMFILE "\n")
    fprintf(FORMFILE "FIELD filename\n")
    fprintf(FORMFILE "FLOC 1 4\n")
    fprintf(FORMFILE "STRFILLIN 21 128\n")
    fprintf(FORMFILE "ENDFIELD \n")
    fprintf(FORMFILE "\n")
    fprintf(FORMFILE "FIELD execute\n")
    fprintf(FORMFILE "FLOC 1 15\n")
    fprintf(FORMFILE "MENUBUTTON \"Run\" 11 3\n")
    fprintf(FORMFILE "ENDFIELD\n")
    fprintf(FORMFILE "\n")
    fprintf(FORMFILE "FIELD cancel\n")
    fprintf(FORMFILE "FLOC 27 15\n")
    fprintf(FORMFILE "MENUBUTTON \"Cancel\" 11 3\n")
    fprintf(FORMFILE "ENDFIELD\n")
    fprintf(FORMFILE "\n")
    fprintf(FORMFILE "ENDTILE\n")
    fprintf(FORMFILE "\n")
    fprintf(FORMFILE "ENDFORM\n")
    close(FORMFILE)
    )
    )
    procedure(XXX_export_colors()
    ;;"main routine for export_colors"
    let((fileList form)
    (XXX_IO_FileName = "")
    (XXX_FormFile = strcat(makeTempFileName(strcat(XXX_TmpDir "Form")) ".form"))
    XXX_export_colors_BuildForm(XXX_FormFile)
    (fileList = setof(x getDirFiles("./") rexMatchp(".alc$" x)))
    (form = axlFormCreate( gensym() XXX_FormFile '(e outer) 'XXX_export_colors_Callback t))
    axlFormTitle( form "Export Colors")
    axlFormSetField( form "view_file" car(fileList))
    foreach(fileName fileList
    axlFormSetField( form "file_list" fileName)
    )
    axlFormDisplay( form)
    )
    )
    procedure(XXX_import_colors()
    ;;"allow user to browse for allegro layer colors ( alc ) file"
    prog((FileName)
    (FileName = axlDMFileBrowse( nil nil ?optFilters " files(*.alc)|*.alc|"))
    if(( stringp(FileName) && (isFile(FileName) == t)) then
    XXX_read_colors(FileName)
    )
    )
    )
    axlCmdRegister( "write_colors" 'XXX_write_colors)
    axlCmdRegister( "export_colors" 'XXX_export_colors)
    axlCmdRegister( "read_colors" 'XXX_read_colors)
    axlCmdRegister( "import_colors" 'XXX_import_colors)

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Verify Answer
    • Reject Answer
    • Cancel
  • soll
    0 soll over 3 years ago in reply to DavidJHutchins

    Thank you for the input! It is good too know that well written SKILL code still works fine after 20 years.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • soll
    0 soll over 3 years ago

    I just realized, looking at the "related topics" on the right that there is a function to do this built in Allegro... File > Export > Parameters...

    Well that was fun anyway.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
Cadence Guidelines

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information