xieeyawen 发表于 2025-2-17 14:28:49

quick_danglings.il代码解析form部分

axlCmdRegister( "quick_danglings" 'quick_danglings ?cmdType "general" )

defvar( psmddo_HELPPAGE "http://www.eda365.com/") ;defvar( s_varName [ g_value ] )定义全局变量,并赋予值or 空


; load("quick_danglings.il")

procedure( quick_danglings()
let(
    ( lDanglingLine
      lDanglingVia
      lIslandShape
      ps_DanglingForm
      ps_DanglingForm_file
      ps_DanglingForm_Port
      lDanglingObject
    );let函数定义局部变量

    when( axlOKToProceed() ;如果Allegro返回t,PCB编辑器已准备好正确执行SKILL命令,否则返回nil。
      axlMsgPut("quick_danglings from www.eda365.com" );axlMsgPut( g_message_format )将消息放入日志文件中

      lDanglingObject = ps_ddoCheck()
      lDanglingLine = car(lDanglingObject)
      ;car(l_list):car( '(a b c) ) => a;car( '((a b c)) => (a b c);car(nil) => nil;
      ;返回列表lDanglingObject的第一个元素,不会改变列表lDanglingObject的内容。
      lDanglingVia = cadr(lDanglingObject)
      ;SKILL使用a和d的任意组合实现所有c…r函数,最多四个字符.cadr is equivalent to car( cdr( l_list))).
      ;举例cdr( '((a b c)) => nil;cdr( '(a b c) ) => (b c);
      lIslandShape = caddr(lDanglingObject)
      ;caddr is equivalent to car( cdr( cdr( l_list))).
      ;举例caddr('(((1 2 3)(4 5 6))(7 8 9))) => nil;cadr('(((1 2 3)(4 5 6))(7 8 9)))=> (7 8 9);
      
      if( lDanglingVia || lDanglingLine || lIslandShape then   
              ;if(g_conditiong_thenExpression[ g_elseExpression ])   
              ;if(g_conditionthen g_thenExpr1 ...[ else g_elseExpr1 ... ])         
          ps_DanglingForm_file = strcat( axlTempDirectory() "./ps_DanglingForm.form" )
          ;strcat(S_string1 [ S_string2 ... ])接收输入字符串或符号并将其连接起来。举例strcat( "l" "ab" "ef" ) => "labef";
          ;返回当前平台的临时目录,和后面字符串合并形成的新字符串作为断头线ps_DanglingForm_file文件路径
          ps_DanglingForm_Port= outfile( ps_DanglingForm_file "w" )
          ;outfile的功能是打开一个输出端口,准备写入文件。
          ;outfile(S_fileName要打开或创建的文件的名称 [ t_mode ] [ g_openHiddenFile如果指定为非nil,则强制使用指定的Windows隐藏文件打开 ])
          ;必须指定t_mode选项(仅指定为w创建新文件写入且任何存在的文件被覆盖或a-打开现有文件增加)
          ; 创建新文件覆盖ps_DanglingForm_file文件   
          fprintf( ps_DanglingForm_Port "FILE_TYPE=FORM_DEFN VERSION=2\n" ) ; 这行内容不能修改,且必须出现在FORM文件的第一行
          fprintf( ps_DanglingForm_Port "FORM\n" )   
;FORM 表示FORM开始,FORM到ENDFORM为FORM之间的内容。
          fprintf( ps_DanglingForm_Port "FIXED\n" )    ;“formtype”有两个选择,一个为“FIXED” 另一个为 “VARIABLE”,但SKILL只支持“FIXED”类型,所以默认该部分填写“FIXED”
          fprintf( ps_DanglingForm_Port "PORT 42 42\n" )    ;“PORT w h” 用于描述FORM的高度和宽度。其中“w-width”描述的是宽度,“h-height”描述的是高度,可根据需要填写。
          fprintf( ps_DanglingForm_Port "HEADER \"Delete Dangling Design Objects\"\n" ); “HEADER "text"” FORM标题栏显示的字符,将"text"替换为自己需要的字符串。
          ;form_header包含以下三个选项1)[{default_button_def}]定义默认按键标签 2)[{popup_def}] 3)[{message_def}]
          fprintf( ps_DanglingForm_Port "TILE\n" )
;必须有ENDTILE结束,否则产生错误。
          ;“{tile_def}”这是FORM的主要部分,FORM上的各个控件都在该部分定义,比如标签、文本框、按键等。
          ;TILE [<tileLabel>];;[{text_def}];[{group_def}];[{field_def}];[{button_def}];[{grid_def}];[{glex_def}]

          fprintf( ps_DanglingForm_Port "FIELD ddoRefresh\n" )            ;定义一个FIELD字段,字段名为ddoRefresh
          fprintf( ps_DanglingForm_Port "FLOC 2 39\n" )                   ;FIELD定义位置
          ;LOC是location(位置)的缩写。
          ;FLOC 是为FIELD 定义坐标的,因为FIELD第一个字母是F;TLOC 是为TEXT 定义坐标的,因为TEXT第一个字母是T
          ;比如GROUP,那么就使用GLOC定义坐标。
          fprintf( ps_DanglingForm_Port "MENUBUTTON \"Refresh\" 10 3\n" ) ;定义一个按键,按键名为“Refresh”,长宽分别为10 3
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )                  ;结束FIELD定义

          fprintf( ps_DanglingForm_Port "FIELD ddoHelp\n" )               ;定义一个FIELD字段,字段名为ddoHelp
          fprintf( ps_DanglingForm_Port "FLOC 16 39\n" )                  ;FIELD定义位置x=16,y=39   
          fprintf( ps_DanglingForm_Port "MENUBUTTON \"Help\" 10 3\n" )    ;定义一个按键,按键名为“Help”,长宽分别为10 3
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )                  ;结束FIELD定义

          fprintf( ps_DanglingForm_Port "FIELD ddoClose\n" )            ;定义一个FIELD字段,字段名为ddoClose
          fprintf( ps_DanglingForm_Port "FLOC 30 39\n" )                  ;FIELD定义位置x=30,y=39
          fprintf( ps_DanglingForm_Port "MENUBUTTON \"Close\" 10 3\n" )   ;定义一个按键,按键名为“Close”,长宽分别为10 3
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )                  ;结束FIELD定义

          fprintf( ps_DanglingForm_Port "TEXT \"Tool from www.eda365.com\"\n" )   ;定义一个文本,文本内容Tool from www.eda365.com
          fprintf( ps_DanglingForm_Port "FLOC 2 1\n" )                            ;FIELD定义位置???
          fprintf( ps_DanglingForm_Port "ENDTEXT\n" )                           ;文本结束

          fprintf( ps_DanglingForm_Port "TABSET tset\n   FLOC 2 3\n      FSIZE 39 35\n")   ;定义一个TAB
                  
                  
                  ;cline:
          fprintf( ps_DanglingForm_Port "TAB \"Dangling Lines\" \n")
;定义一个TAB,名字Dangling Lines
          fprintf( ps_DanglingForm_Port "TEXT \"Dangling Line:\"\n" )       ;定义一个文本,文本内容Dangling Line:
          fprintf( ps_DanglingForm_Port "TLOC 2 1\n" )                      ;TEXT 定义坐标的
          fprintf( ps_DanglingForm_Port "ENDTEXT\n" )                     ;文本结束

          fprintf( ps_DanglingForm_Port "TEXT \n" )                         ;定义一个文本      
          fprintf( ps_DanglingForm_Port "FLOC 12 1\n" )                     ;FIELD定义位置???
          fprintf( ps_DanglingForm_Port "INFO ddoLineInfo 10\n" )         
          ;INFO文本???
          ;ddoLineInfo断头线数量信息
          ;后面有程序axlFormSetField( ps_DanglingForm "ddoLineInfo" length(lDanglingLine) )
          ;10 应该是字体大小???
          fprintf( ps_DanglingForm_Port "ENDTEXT\n" )                     ;文本结束

          fprintf( ps_DanglingForm_Port "FIELD ddoLineList\n" )             ;定义一个FIELD字段,字段名为ddoLineList
          fprintf( ps_DanglingForm_Port "FLOC 2 3\n" )                      ;FIELD定义位置
          fprintf( ps_DanglingForm_Port "LIST \"\" 34 14\n" )               ;定义一个LIST,内容\,位置34 14短路线的list内容
          fprintf( ps_DanglingForm_Port "OPTIONS multiselect\n" )         ;OPTIONS multiselect多选下拉菜单组件,可以多选断头线的选项
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )                      ;FIELD字段结束

          fprintf( ps_DanglingForm_Port "FIELD ddoLinesDel\n" )             ;定义一个FIELD字段,字段名为ddoLinesDel
          fprintf( ps_DanglingForm_Port "FLOC 13 30\n" )                  ;FIELD定义位置
          fprintf( ps_DanglingForm_Port "MENUBUTTON \"Delete\" 12 3\n" )    ;定义一个按键,按键名为“Delete”,长宽分别为12 3
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )                      ;FIELD字段结束            

          fprintf(ps_DanglingForm_Port "ENDTAB\n")                        
;TAB结束
                  
                  
                  
                  ;via

          fprintf(ps_DanglingForm_Port "TAB \"Dangling Vias\" \n")
;定义一个TAB,名字Dangling Vias
          fprintf( ps_DanglingForm_Port "TEXT \"Dangling Vias:\"\n" )
          fprintf( ps_DanglingForm_Port "TLOC 2 1\n" )
          fprintf( ps_DanglingForm_Port "ENDTEXT\n" )

          fprintf( ps_DanglingForm_Port "TEXT \n" )
          fprintf( ps_DanglingForm_Port "FLOC 12 1\n" )
          fprintf( ps_DanglingForm_Port "INFO ddoViaInfo 10\n" )               
          ;INFO文本
          ;ddoViaInfo悬空过孔数量信息
          ;后面有程序axlFormSetField( ps_DanglingForm "ddoViaInfo" length(lDanglingVia) )
          ;10 应该是字体大小???
          fprintf( ps_DanglingForm_Port "ENDTEXT\n" )

          fprintf( ps_DanglingForm_Port "FIELD ddoViaList\n" )
          fprintf( ps_DanglingForm_Port "FLOC 2 3\n" )
          fprintf( ps_DanglingForm_Port "LIST \"\" 34 14\n" )
          fprintf( ps_DanglingForm_Port "OPTIONS multiselect\n" )            ;OPTIONS multiselect多选下拉菜单组件,可以多选悬空过孔的选项
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )

          fprintf( ps_DanglingForm_Port "FIELD ddoViasDel\n" )
          fprintf( ps_DanglingForm_Port "FLOC 2 30\n" )
          fprintf( ps_DanglingForm_Port "MENUBUTTON \"Delete\" 12 3\n" )       ;定义一个按键,按键名为“Delete”,长宽分别为12 3
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )                  

          fprintf( ps_DanglingForm_Port "FIELD ddoAssign\n" )
          fprintf( ps_DanglingForm_Port "FLOC 24 30\n" )
          fprintf( ps_DanglingForm_Port "MENUBUTTON \"Change Net\" 12 3\n" )   ;定义一个按键,按键名为“Change Net”,长宽分别为12 3
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )

          fprintf(ps_DanglingForm_Port "ENDTAB\n")
;TAB结束
                  
                  ;shape

          fprintf(ps_DanglingForm_Port "TAB \"Island Shapes\" \n")
          fprintf( ps_DanglingForm_Port "TEXT \"Island Shapes:\"\n" )
          fprintf( ps_DanglingForm_Port "TLOC 2 1\n" )
          fprintf( ps_DanglingForm_Port "ENDTEXT\n" )

          fprintf( ps_DanglingForm_Port "TEXT \n" )
          fprintf( ps_DanglingForm_Port "FLOC 12 1\n" )
          fprintf( ps_DanglingForm_Port "INFO ddoShapeInfo 10\n" )
          ;INFO文本???
          ;ddoShapeInfo孤岛数量信息
          ;后面有程序axlFormSetField( ps_DanglingForm "ddoShapeInfo" length(lIslandShape) )
          ;10 应该是字体大小???          
          fprintf( ps_DanglingForm_Port "ENDTEXT\n" )

          fprintf( ps_DanglingForm_Port "FIELD ddoShapeList\n" )
          fprintf( ps_DanglingForm_Port "FLOC 2 3\n" )
          fprintf( ps_DanglingForm_Port "LIST \"\" 34 14\n" )
          fprintf( ps_DanglingForm_Port "OPTIONS multiselect\n" )
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )

          fprintf( ps_DanglingForm_Port "FIELD ddoShapesDel\n" )
          fprintf( ps_DanglingForm_Port "FLOC 13 30\n" )
          fprintf( ps_DanglingForm_Port "MENUBUTTON \"Delete\" 12 3\n" )
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )                  

          fprintf(ps_DanglingForm_Port "ENDTAB\n")

          fprintf(ps_DanglingForm_Port "ENDTABSET\n")

          fprintf( ps_DanglingForm_Port "ENDTILE\n" );ENDTILE与前面TILE照应,表示TILE结束
          fprintf( ps_DanglingForm_Port "ENDFORM\n" );ENDFORM与前面FORM照应,表示FORM结束

          close( ps_DanglingForm_Port ) ;排空、关闭和释放端口。关闭文件时,它会释放与p_port关联的file*。
          ;不要使用此函数在piport、poport、stdin、stdout和stderr上。

          ps_DanglingForm = axlFormCreate( (gensym) ps_DanglingForm_file '(e outer) 'ps_DanglingForm_action t)
          ;axlFormCreate(s_formHandlet_formfile/(t_formName t_contents)g_formActiong_nonBlock)
          ;支持“fixed”类型的表单,如果t_formfile包含任何可变图块,则会失败。
          ;这个函数不显示表单。请使用axlFormDisplay显示表单。
          ;支持另一种接口,允许将表单文件的内容嵌入到skill代码。
          ;s_formHandle代表FORM的句柄,就是该FORM在那个窗口上显示,一般这个参数我们使用 (gensym)
          ;t_formfile代表FORM文件的完整路径,即form文件路径为ps_DanglingForm_file字符串内容。
          ; :可选参数,这个代表FORM的显示位置。当使用nil 时,allegro会调用默认的位置显示。
;下面是位置参数(注,使用的时候选择括号中的字母即可)
;north(n) northeast(ne) east(e) southeast(se) south(s) southwest(sw) west(w) northwest(nw) center(c)
          ; 选择Inner or Outer 设置FORM显示在ALLEGRO里面还是外面,默认为里面即 Inner
          ;g_formAction对FORM所有触发事件响应的函数,比如对点击某个按钮,则会执行该函数。事件函数为ps_DanglingForm_action
          ;g_nonBlock 可设置FORM是否在non-blocking模式下运行。
          ; 可选参数,如果为t,那么form返回的所有值都为string格式。一般设置为nil

          axlFormSetField( ps_DanglingForm "ddoLineList" lDanglingLine )
          ;axlFormSetField(r_formt_fieldg_value/nil) 在开放的FORM表r_form里,将t_field设置为g_value值
          ;即ps_DanglingForm里,把"ddoLineList"列表设置为lDanglingLine 【其中 lDanglingLine = car(lDanglingObject),即lDanglingObject列表的第一个元素】   
;r_form Form dbid.开放的FORM表r_form
;t_field 字段名称。字段名是字符串或符号。
;字段名有多种,有List Field(field is named "list");Color field (field is named "color");Tab field (field is named "tab")等
;g_value 字段的期望值。可以是字符串、布尔值、整数或浮点数或列表;字段类型的函数。
          axlFormSetField( ps_DanglingForm "ddoViaList" lDanglingVia )
          axlFormSetField( ps_DanglingForm "ddoShapeList" lIslandShape )
          axlFormSetField( ps_DanglingForm "ddoLineInfo" length(lDanglingLine) );断头线数量
          axlFormSetField( ps_DanglingForm "ddoViaInfo" length(lDanglingVia) )    ;悬空过孔数量
          axlFormSetField( ps_DanglingForm "ddoShapeInfo" length(lIslandShape) );孤岛数量
          axlFormColorize( ps_DanglingForm "ddoLineInfo" 'text 'red )             ;断头线数量信息高亮成红色
          axlFormColorize( ps_DanglingForm "ddoViaInfo" 'text 'red )            ;悬空过孔数量信息高亮成红色
          axlFormColorize( ps_DanglingForm "ddoShapeInfo" 'text 'red )            ;孤岛数量信息高亮成红色

          axlFormDisplay( ps_DanglingForm )         ;axlFormSetField函数不显示表单,使用axlFormDisplay显示表单。
          when( lDanglingLine
            axlMsgPut(sprintf(nil "E- %d Dangling Lines, check Dangling Lines Tab" length(lDanglingLine) ))
          );在allegro的状态栏里输出断头线数量
          when( lDanglingVia
            axlMsgPut(sprintf(nil "E- %d Dangling Via, check Dangling Vias Tab" length(lDanglingVia) ))
          );在allegro的状态栏里输出悬空过孔数量
          when( lIslandShape
            axlMsgPut(sprintf(nil "E- %d Island Shape, check Island Shapes Tab" length(lIslandShape) ))
          );在allegro的状态栏里输出孤岛数量
          axlUIWPrint( ps_DanglingForm "Select Dangling, Island Line/Via/Shape..." )
          ;axlUIWPrint(r_window/nilt_formatString)
          ;UIW-User Interface window用户界面窗口
          ;r_window/nil消息显示在主窗口外,为空则在主窗口显示,此处为ps_DanglingForm,显示在主窗口外的FORM表ps_DanglingForm窗口上
          ;t_formatString 替换参数为字符串"Select Dangling, Island Line/Via/Shape...",这个是FORM表ps_DanglingForm窗口上的增加的内容,位置默认在最下脚。
          ;打印任意数量的替换参数t_formatString
          axlUIWDisableQuit(ps_DanglingForm);axlUIDisableQuit(o_window) 禁用系统菜单“退出”选项,因此用户无法选择它来关闭窗口。就是不能直接关掉ps_DanglingForm窗口
          deleteFile(ps_DanglingForm_file);将创建的ps_DanglingForm_file文件删除
      else
          axlMsgPut("I- No dangling, island line/via/shape problems");在allegro的状态栏里输出I- No dangling, island line/via/shape problems
      ); end if lDanglingVia || lDanglingLine || lIslandShape
    ); end when
); end let
); end quick_danglings


;FORM编程的一般步骤
;1.创建form文件
;可以自己提前将 FORM 代码写到单独的form文件,或者将代码嵌入到SKILL文件中,在SKILL执行过程中创建form文件 。
;2.使用 axlFormCreate 函数打开 FORM
;3.使用 axlFormSetField 函数初始化 FORM 中的各个字段
;4.使用 axlFormDisplay 函数显示 FORM
;5.使用 axlFormCallback 与用户交互
;6.使用 axlFormClose 关闭 FROM

xieeyawen 发表于 2025-2-17 14:30:47

axlCmdRegister( "quick_danglings" 'quick_danglings ?cmdType "general" )

defvar( psmddo_HELPPAGE "http://www.eda365.com/") ;defvar( s_varName [ g_value ] )定义全局变量,并赋予值or 空


; load("quick_danglings.il")

procedure( quick_danglings()
let(
    ( lDanglingLine
      lDanglingVia
      lIslandShape
      ps_DanglingForm
      ps_DanglingForm_file
      ps_DanglingForm_Port
      lDanglingObject
    );let函数定义局部变量

    when( axlOKToProceed() ;如果Allegro返回t,PCB编辑器已准备好正确执行SKILL命令,否则返回nil。
      axlMsgPut("quick_danglings from www.eda365.com" );axlMsgPut( g_message_format )将消息放入日志文件中

      lDanglingObject = ps_ddoCheck()
      lDanglingLine = car(lDanglingObject)
      ;car(l_list):car( '(a b c) ) => a;car( '((a b c)) => (a b c);car(nil) => nil;
      ;返回列表lDanglingObject的第一个元素,不会改变列表lDanglingObject的内容。
      lDanglingVia = cadr(lDanglingObject)
      ;SKILL使用a和d的任意组合实现所有c…r函数,最多四个字符.cadr is equivalent to car( cdr( l_list))).
      ;举例cdr( '((a b c)) => nil;cdr( '(a b c) ) => (b c);
      lIslandShape = caddr(lDanglingObject)
      ;caddr is equivalent to car( cdr( cdr( l_list))).
      ;举例caddr('(((1 2 3)(4 5 6))(7 8 9))) => nil;cadr('(((1 2 3)(4 5 6))(7 8 9)))=> (7 8 9);
      
      if( lDanglingVia || lDanglingLine || lIslandShape then   
              ;if(g_conditiong_thenExpression[ g_elseExpression ])   
              ;if(g_conditionthen g_thenExpr1 ...[ else g_elseExpr1 ... ])         
          ps_DanglingForm_file = strcat( axlTempDirectory() "./ps_DanglingForm.form" )
          ;strcat(S_string1 [ S_string2 ... ])接收输入字符串或符号并将其连接起来。举例strcat( "l" "ab" "ef" ) => "labef";
          ;返回当前平台的临时目录,和后面字符串合并形成的新字符串作为断头线ps_DanglingForm_file文件路径
          ps_DanglingForm_Port= outfile( ps_DanglingForm_file "w" )
          ;outfile的功能是打开一个输出端口,准备写入文件。
          ;outfile(S_fileName要打开或创建的文件的名称 [ t_mode ] [ g_openHiddenFile如果指定为非nil,则强制使用指定的Windows隐藏文件打开 ])
          ;必须指定t_mode选项(仅指定为w创建新文件写入且任何存在的文件被覆盖或a-打开现有文件增加)
          ; 创建新文件覆盖ps_DanglingForm_file文件   
          fprintf( ps_DanglingForm_Port "FILE_TYPE=FORM_DEFN VERSION=2\n" ) ; 这行内容不能修改,且必须出现在FORM文件的第一行
          fprintf( ps_DanglingForm_Port "FORM\n" )   
;FORM 表示FORM开始,FORM到ENDFORM为FORM之间的内容。
          fprintf( ps_DanglingForm_Port "FIXED\n" )    ;“formtype”有两个选择,一个为“FIXED” 另一个为 “VARIABLE”,但SKILL只支持“FIXED”类型,所以默认该部分填写“FIXED”
          fprintf( ps_DanglingForm_Port "PORT 42 42\n" )    ;“PORT w h” 用于描述FORM的高度和宽度。其中“w-width”描述的是宽度,“h-height”描述的是高度,可根据需要填写。
          fprintf( ps_DanglingForm_Port "HEADER \"Delete Dangling Design Objects\"\n" ); “HEADER "text"” FORM标题栏显示的字符,将"text"替换为自己需要的字符串。
          ;form_header包含以下三个选项1)[{default_button_def}]定义默认按键标签 2)[{popup_def}] 3)[{message_def}]
          fprintf( ps_DanglingForm_Port "TILE\n" )
;必须有ENDTILE结束,否则产生错误。
          ;“{tile_def}”这是FORM的主要部分,FORM上的各个控件都在该部分定义,比如标签、文本框、按键等。
          ;TILE [<tileLabel>];;[{text_def}];[{group_def}];[{field_def}];[{button_def}];[{grid_def}];[{glex_def}]

          fprintf( ps_DanglingForm_Port "FIELD ddoRefresh\n" )            ;定义一个FIELD字段,字段名为ddoRefresh
          fprintf( ps_DanglingForm_Port "FLOC 2 39\n" )                   ;FIELD定义位置
          ;LOC是location(位置)的缩写。
          ;FLOC 是为FIELD 定义坐标的,因为FIELD第一个字母是F;TLOC 是为TEXT 定义坐标的,因为TEXT第一个字母是T
          ;比如GROUP,那么就使用GLOC定义坐标。
          fprintf( ps_DanglingForm_Port "MENUBUTTON \"Refresh\" 10 3\n" ) ;定义一个按键,按键名为“Refresh”,长宽分别为10 3
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )                  ;结束FIELD定义

          fprintf( ps_DanglingForm_Port "FIELD ddoHelp\n" )               ;定义一个FIELD字段,字段名为ddoHelp
          fprintf( ps_DanglingForm_Port "FLOC 16 39\n" )                  ;FIELD定义位置x=16,y=39   
          fprintf( ps_DanglingForm_Port "MENUBUTTON \"Help\" 10 3\n" )    ;定义一个按键,按键名为“Help”,长宽分别为10 3
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )                  ;结束FIELD定义

          fprintf( ps_DanglingForm_Port "FIELD ddoClose\n" )            ;定义一个FIELD字段,字段名为ddoClose
          fprintf( ps_DanglingForm_Port "FLOC 30 39\n" )                  ;FIELD定义位置x=30,y=39
          fprintf( ps_DanglingForm_Port "MENUBUTTON \"Close\" 10 3\n" )   ;定义一个按键,按键名为“Close”,长宽分别为10 3
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )                  ;结束FIELD定义

          fprintf( ps_DanglingForm_Port "TEXT \"Tool from www.eda365.com\"\n" )   ;定义一个文本,文本内容Tool from www.eda365.com
          fprintf( ps_DanglingForm_Port "FLOC 2 1\n" )                            ;FIELD定义位置???
          fprintf( ps_DanglingForm_Port "ENDTEXT\n" )                           ;文本结束

          fprintf( ps_DanglingForm_Port "TABSET tset\n   FLOC 2 3\n      FSIZE 39 35\n")   ;定义一个TAB
                  
                  
                  ;cline:
          fprintf( ps_DanglingForm_Port "TAB \"Dangling Lines\" \n")
;定义一个TAB,名字Dangling Lines
          fprintf( ps_DanglingForm_Port "TEXT \"Dangling Line:\"\n" )       ;定义一个文本,文本内容Dangling Line:
          fprintf( ps_DanglingForm_Port "TLOC 2 1\n" )                      ;TEXT 定义坐标的
          fprintf( ps_DanglingForm_Port "ENDTEXT\n" )                     ;文本结束

          fprintf( ps_DanglingForm_Port "TEXT \n" )                         ;定义一个文本      
          fprintf( ps_DanglingForm_Port "FLOC 12 1\n" )                     ;FIELD定义位置???
          fprintf( ps_DanglingForm_Port "INFO ddoLineInfo 10\n" )         
          ;INFO文本???
          ;ddoLineInfo断头线数量信息
          ;后面有程序axlFormSetField( ps_DanglingForm "ddoLineInfo" length(lDanglingLine) )
          ;10 应该是字体大小???
          fprintf( ps_DanglingForm_Port "ENDTEXT\n" )                     ;文本结束

          fprintf( ps_DanglingForm_Port "FIELD ddoLineList\n" )             ;定义一个FIELD字段,字段名为ddoLineList
          fprintf( ps_DanglingForm_Port "FLOC 2 3\n" )                      ;FIELD定义位置
          fprintf( ps_DanglingForm_Port "LIST \"\" 34 14\n" )               ;定义一个LIST,内容\,位置34 14短路线的list内容
          fprintf( ps_DanglingForm_Port "OPTIONS multiselect\n" )         ;OPTIONS multiselect多选下拉菜单组件,可以多选断头线的选项
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )                      ;FIELD字段结束

          fprintf( ps_DanglingForm_Port "FIELD ddoLinesDel\n" )             ;定义一个FIELD字段,字段名为ddoLinesDel
          fprintf( ps_DanglingForm_Port "FLOC 13 30\n" )                  ;FIELD定义位置
          fprintf( ps_DanglingForm_Port "MENUBUTTON \"Delete\" 12 3\n" )    ;定义一个按键,按键名为“Delete”,长宽分别为12 3
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )                      ;FIELD字段结束            

          fprintf(ps_DanglingForm_Port "ENDTAB\n")                        
;TAB结束
                  
                  
                  
                  ;via

          fprintf(ps_DanglingForm_Port "TAB \"Dangling Vias\" \n")
;定义一个TAB,名字Dangling Vias
          fprintf( ps_DanglingForm_Port "TEXT \"Dangling Vias:\"\n" )
          fprintf( ps_DanglingForm_Port "TLOC 2 1\n" )
          fprintf( ps_DanglingForm_Port "ENDTEXT\n" )

          fprintf( ps_DanglingForm_Port "TEXT \n" )
          fprintf( ps_DanglingForm_Port "FLOC 12 1\n" )
          fprintf( ps_DanglingForm_Port "INFO ddoViaInfo 10\n" )               
          ;INFO文本
          ;ddoViaInfo悬空过孔数量信息
          ;后面有程序axlFormSetField( ps_DanglingForm "ddoViaInfo" length(lDanglingVia) )
          ;10 应该是字体大小???
          fprintf( ps_DanglingForm_Port "ENDTEXT\n" )

          fprintf( ps_DanglingForm_Port "FIELD ddoViaList\n" )
          fprintf( ps_DanglingForm_Port "FLOC 2 3\n" )
          fprintf( ps_DanglingForm_Port "LIST \"\" 34 14\n" )
          fprintf( ps_DanglingForm_Port "OPTIONS multiselect\n" )            ;OPTIONS multiselect多选下拉菜单组件,可以多选悬空过孔的选项
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )

          fprintf( ps_DanglingForm_Port "FIELD ddoViasDel\n" )
          fprintf( ps_DanglingForm_Port "FLOC 2 30\n" )
          fprintf( ps_DanglingForm_Port "MENUBUTTON \"Delete\" 12 3\n" )       ;定义一个按键,按键名为“Delete”,长宽分别为12 3
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )                  

          fprintf( ps_DanglingForm_Port "FIELD ddoAssign\n" )
          fprintf( ps_DanglingForm_Port "FLOC 24 30\n" )
          fprintf( ps_DanglingForm_Port "MENUBUTTON \"Change Net\" 12 3\n" )   ;定义一个按键,按键名为“Change Net”,长宽分别为12 3
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )

          fprintf(ps_DanglingForm_Port "ENDTAB\n")
;TAB结束
                  
                  ;shape

          fprintf(ps_DanglingForm_Port "TAB \"Island Shapes\" \n")
          fprintf( ps_DanglingForm_Port "TEXT \"Island Shapes:\"\n" )
          fprintf( ps_DanglingForm_Port "TLOC 2 1\n" )
          fprintf( ps_DanglingForm_Port "ENDTEXT\n" )

          fprintf( ps_DanglingForm_Port "TEXT \n" )
          fprintf( ps_DanglingForm_Port "FLOC 12 1\n" )
          fprintf( ps_DanglingForm_Port "INFO ddoShapeInfo 10\n" )
          ;INFO文本???
          ;ddoShapeInfo孤岛数量信息
          ;后面有程序axlFormSetField( ps_DanglingForm "ddoShapeInfo" length(lIslandShape) )
          ;10 应该是字体大小???         
          fprintf( ps_DanglingForm_Port "ENDTEXT\n" )

          fprintf( ps_DanglingForm_Port "FIELD ddoShapeList\n" )
          fprintf( ps_DanglingForm_Port "FLOC 2 3\n" )
          fprintf( ps_DanglingForm_Port "LIST \"\" 34 14\n" )
          fprintf( ps_DanglingForm_Port "OPTIONS multiselect\n" )
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )

          fprintf( ps_DanglingForm_Port "FIELD ddoShapesDel\n" )
          fprintf( ps_DanglingForm_Port "FLOC 13 30\n" )
          fprintf( ps_DanglingForm_Port "MENUBUTTON \"Delete\" 12 3\n" )
          fprintf( ps_DanglingForm_Port "ENDFIELD\n" )                  

          fprintf(ps_DanglingForm_Port "ENDTAB\n")

          fprintf(ps_DanglingForm_Port "ENDTABSET\n")

          fprintf( ps_DanglingForm_Port "ENDTILE\n" );ENDTILE与前面TILE照应,表示TILE结束
          fprintf( ps_DanglingForm_Port "ENDFORM\n" );ENDFORM与前面FORM照应,表示FORM结束

          close( ps_DanglingForm_Port ) ;排空、关闭和释放端口。关闭文件时,它会释放与p_port关联的file*。
          ;不要使用此函数在piport、poport、stdin、stdout和stderr上。

          ps_DanglingForm = axlFormCreate( (gensym) ps_DanglingForm_file '(e outer) 'ps_DanglingForm_action t)
          ;axlFormCreate(s_formHandlet_formfile/(t_formName t_contents)g_formActiong_nonBlock)
          ;支持“fixed”类型的表单,如果t_formfile包含任何可变图块,则会失败。
          ;这个函数不显示表单。请使用axlFormDisplay显示表单。
          ;支持另一种接口,允许将表单文件的内容嵌入到skill代码。
          ;s_formHandle代表FORM的句柄,就是该FORM在那个窗口上显示,一般这个参数我们使用 (gensym)
          ;t_formfile代表FORM文件的完整路径,即form文件路径为ps_DanglingForm_file字符串内容。
          ; :可选参数,这个代表FORM的显示位置。当使用nil 时,allegro会调用默认的位置显示。
;下面是位置参数(注,使用的时候选择括号中的字母即可)
;north(n) northeast(ne) east(e) southeast(se) south(s) southwest(sw) west(w) northwest(nw) center(c)
          ; 选择Inner or Outer 设置FORM显示在ALLEGRO里面还是外面,默认为里面即 Inner
          ;g_formAction对FORM所有触发事件响应的函数,比如对点击某个按钮,则会执行该函数。事件函数为ps_DanglingForm_action
          ;g_nonBlock 可设置FORM是否在non-blocking模式下运行。
          ; 可选参数,如果为t,那么form返回的所有值都为string格式。一般设置为nil

          axlFormSetField( ps_DanglingForm "ddoLineList" lDanglingLine )
          ;axlFormSetField(r_formt_fieldg_value/nil) 在开放的FORM表r_form里,将t_field设置为g_value值
          ;即ps_DanglingForm里,把"ddoLineList"列表设置为lDanglingLine 【其中 lDanglingLine = car(lDanglingObject),即lDanglingObject列表的第一个元素】   
;r_form Form dbid.开放的FORM表r_form
;t_field 字段名称。字段名是字符串或符号。
;字段名有多种,有List Field(field is named "list");Color field (field is named "color");Tab field (field is named "tab")等
;g_value 字段的期望值。可以是字符串、布尔值、整数或浮点数或列表;字段类型的函数。
          axlFormSetField( ps_DanglingForm "ddoViaList" lDanglingVia )
          axlFormSetField( ps_DanglingForm "ddoShapeList" lIslandShape )
          axlFormSetField( ps_DanglingForm "ddoLineInfo" length(lDanglingLine) );断头线数量
          axlFormSetField( ps_DanglingForm "ddoViaInfo" length(lDanglingVia) )    ;悬空过孔数量
          axlFormSetField( ps_DanglingForm "ddoShapeInfo" length(lIslandShape) );孤岛数量
          axlFormColorize( ps_DanglingForm "ddoLineInfo" 'text 'red )             ;断头线数量信息高亮成红色
          axlFormColorize( ps_DanglingForm "ddoViaInfo" 'text 'red )            ;悬空过孔数量信息高亮成红色
          axlFormColorize( ps_DanglingForm "ddoShapeInfo" 'text 'red )            ;孤岛数量信息高亮成红色

          axlFormDisplay( ps_DanglingForm )         ;axlFormSetField函数不显示表单,使用axlFormDisplay显示表单。
          when( lDanglingLine
            axlMsgPut(sprintf(nil "E- %d Dangling Lines, check Dangling Lines Tab" length(lDanglingLine) ))
          );在allegro的状态栏里输出断头线数量
          when( lDanglingVia
            axlMsgPut(sprintf(nil "E- %d Dangling Via, check Dangling Vias Tab" length(lDanglingVia) ))
          );在allegro的状态栏里输出悬空过孔数量
          when( lIslandShape
            axlMsgPut(sprintf(nil "E- %d Island Shape, check Island Shapes Tab" length(lIslandShape) ))
          );在allegro的状态栏里输出孤岛数量
          axlUIWPrint( ps_DanglingForm "Select Dangling, Island Line/Via/Shape..." )
          ;axlUIWPrint(r_window/nilt_formatString)
          ;UIW-User Interface window用户界面窗口
          ;r_window/nil消息显示在主窗口外,为空则在主窗口显示,此处为ps_DanglingForm,显示在主窗口外的FORM表ps_DanglingForm窗口上
          ;t_formatString 替换参数为字符串"Select Dangling, Island Line/Via/Shape...",这个是FORM表ps_DanglingForm窗口上的增加的内容,位置默认在最下脚。
          ;打印任意数量的替换参数t_formatString
          axlUIWDisableQuit(ps_DanglingForm);axlUIDisableQuit(o_window) 禁用系统菜单“退出”选项,因此用户无法选择它来关闭窗口。就是不能直接关掉ps_DanglingForm窗口
          deleteFile(ps_DanglingForm_file);将创建的ps_DanglingForm_file文件删除
      else
          axlMsgPut("I- No dangling, island line/via/shape problems");在allegro的状态栏里输出I- No dangling, island line/via/shape problems
      ); end if lDanglingVia || lDanglingLine || lIslandShape
    ); end when
); end let
); end quick_danglings


;FORM编程的一般步骤
;1.创建form文件
;可以自己提前将 FORM 代码写到单独的form文件,或者将代码嵌入到SKILL文件中,在SKILL执行过程中创建form文件 。
;2.使用 axlFormCreate 函数打开 FORM
;3.使用 axlFormSetField 函数初始化 FORM 中的各个字段
;4.使用 axlFormDisplay 函数显示 FORM
;5.使用 axlFormCallback 与用户交互
;6.使用 axlFormClose 关闭 FROM

xieeyawen 发表于 2025-2-17 14:31:25

红色部分不知道怎么解释,有高手解释一下吗

xieeyawen 发表于 2025-2-17 14:38:38

axlUIWPrint函数界面区别

本帖最后由 xieeyawen 于 2025-2-17 14:41 编辑


axlUIWPrint函数界面区别

xieeyawen 发表于 2025-2-17 14:39:40

axlMsgPut函数显示在allegro窗口上

本帖最后由 xieeyawen 于 2025-2-17 14:44 编辑

axlMsgPut(sprintf(nil "E- %d Dangling Lines, check Dangling Lines Tab" length(lDanglingLine) ))

xieeyawen 发表于 2025-2-17 18:23:05

procedure( ps_DanglingForm_action( ps_DanglingForm1 );ps_DanglingForm_action函数,变量ps_DanglingForm1,此函数主要用途是判断用户在form里面的一些操作和allegro视图交互功能
let(
    ( lDanglingVia
      lDanglingLine
      lIslandShape
      lIssueCline
      lTemp
      sLayer
      fStartX
      fStartY
      fEndX
      fEndY
      sStart
      sEnd
      lSeg
      lStartA
      lStartB
      lEndA
      lEndB
      sStartTempA
      sStartTempB
      sEndTempA
      sEndTempB
      fCoordX
      fCoordY
      dVia
      lVia
      fFindRange
      lClines
      sNet
      sMessage
      lViaInfo
      lShapeInfo
      lShape
      dShape
      lDanglingObject
      lSys
      lCoord
      bShape
      bDRC
    ) ;定义局部变量
    fFindRange = axlMKSConvert(1 "MILS")
    ;axlMKSConvert(1 "MILS") => 0.0254即1的单位是mil,输出单位nil即输出单位为当前设计单位(现在设计单位用的mm)值为0.0254
    ;axlMKSConvert(1 "mm" "mils") => 39.37008即1的单位是mm,输出单位为指定单位mils,值为39.37008
    case( ps_DanglingForm1->curField            ;curField-current Field当前Field字段,同样有curValue-当前值
    ;case(g_selectionExprl_clause1[ l_clause2 ... ])
    ;例子nameofmonth = "February";month = case( nameofmonth("January" 1) ("February" 2) (t 'Other))=> 2
    ;此处的curField,用户在form里可以点击的有Refresh,linelist,vialist,shapelist,lineDel,viaDel,shapeDel,Help,close,Assign(change Net)
      ( "ddoRefresh"
      axlClearSelSet()      
      lDanglingObject = ps_ddoCheck()
      lDanglingLine = car(lDanglingObject)
      lDanglingVia = cadr(lDanglingObject)
      lIslandShape = caddr(lDanglingObject)

      if( lDanglingLine || lDanglingVia || lIslandShape then
          when( lDanglingLine
            axlMsgPut(sprintf(nil "E- %d Dangling Lines, check Dangling Lines Tab" length(lDanglingLine) ))
          )
          when( lDanglingVia
            axlMsgPut(sprintf(nil "E- %d Dangling Via, check Dangling Vias Tab" length(lDanglingVia) ))
          )
          when( lIslandShape
            axlMsgPut(sprintf(nil "E- %d Island Shape, check Island Shapes Tab" length(lIslandShape) ))
          )
      else
          axlMsgPut("I- No Dangling, Island Lines/Vias/Shapes")
      )
      axlFormListDeleteAll( ps_DanglingForm1 "ddoLineList" )
      axlFormListDeleteAll( ps_DanglingForm1 "ddoViaList" )
      axlFormListDeleteAll( ps_DanglingForm1 "ddoShapeList" )
      axlFormSetField( ps_DanglingForm1 "ddoLineList" lDanglingLine )
      axlFormSetField( ps_DanglingForm1 "ddoViaList" lDanglingVia )
      axlFormSetField( ps_DanglingForm1 "ddoShapeList" lIslandShape )
      axlFormSetField( ps_DanglingForm1 "ddoLineInfo" length(lDanglingLine) )
      axlFormSetField( ps_DanglingForm1 "ddoViaInfo" length(lDanglingVia) )
      axlFormSetField( ps_DanglingForm1 "ddoShapeInfo" length(lIslandShape) )
      axlFormColorize(ps_DanglingForm1 "ddoLineInfo" 'text 'red)
      axlFormColorize(ps_DanglingForm1 "ddoViaInfo" 'text 'red)
      axlFormColorize(ps_DanglingForm1 "ddoShapeInfo" 'text 'red)
      );case的第一种情况"ddoRefresh"
      ( "ddoLineList"
      lDanglingLine = axlFormListGetSelItems(ps_DanglingForm1 "ddoLineList")   
      ;axlFormListGetSelItems(r_formt_field)即GET获得FORM表里选择项目Select-Items的表list,即返回一个form(a list of string),值为断头线这个field里列表被多选的部分。
      axlClearSelSet()      ;取消所有选择
      axlSetFindFilter( ?enabled'("noall" "clines") ?onButtons '("clines") )    ;取消选项并选择走线   
      lIssueCline = nil       ;初始化lIssueCline
      axlVisibleDesign(nil)   ;设计可显示
      foreach( sline lDanglingLine   ;在form弹窗里被用户多选的那部分断头线列表里进行遍历
          lTemp = parseString( sline "," )         
          sLayer = car( lTemp )
          lCoord = parseString(caddr(lTemp) " ()to")
          fStartX = atof(car(lCoord))
          fStartY = atof(cadr(lCoord))
          fEndX = atof(caddr(lCoord))
          fEndY = atof(nth(3 lCoord))
          axlVisibleLayer(strcat("etch/" sLayer) t)         
          axlVisibleLayer(strcat("via class/" sLayer) t)
          axlVisibleLayer(strcat("pin/" sLayer) t)      
          sStart = sprintf(nil "x%0.3fy%0.3f" fStartX fStartY)
          sEnd = sprintf(nil "x%0.3fy%0.3f" fEndX fEndY)
          lClines = axlGetSelSet(
                      axlSingleSelectBox(
                        list((fStartX-fFindRange):(fStartY-fFindRange)
                        (fStartX+fFindRange):(fStartY+fFindRange))      
                      ))
          axlClearSelSet()         
          if( lClines then
            foreach( cline lClines
            lSeg = cline->segments
            lStartA = car(car(lSeg)->startEnd)
            lEndA = cadr(car(last(lSeg))->startEnd)
            sStartTempA = sprintf( nil "x%0.3fy%0.3f" car(lStartA) cadr(lStartA))
            sEndTempA = sprintf( nil "x%0.3fy%0.3f" car(lEndA) cadr(lEndA))

            lStartB = car(car(last(lSeg))->startEnd)
            lEndB = cadr(car(lSeg)->startEnd)
            sStartTempB = sprintf( nil "x%0.3fy%0.3f" car(lStartB) cadr(lStartB))
            sEndTempB = sprintf( nil "x%0.3fy%0.3f" car(lEndB) cadr(lEndB))

            when( (sStartTempA==sStart && sEndTempA==sEnd) ||
                  (sStartTempA==sEnd && sEndTempA==sStart) ||
                  (sStartTempB==sStart && sEndTempB==sEnd) ||
                  (sStartTempB==sEnd && sEndTempB==sStart)
                lIssueCline = cons( cline lIssueCline )
            )
            )         
          else
            axlUIWPrint( ps_DanglingForm1 "Can not find the cline, find it manually..." )
          )
      )
      axlHighlightObject(lIssueCline)
      axlZoomToDbid(lIssueCline t)   
      );case的第二种情况"ddoLineList"
      ( "ddoViaList"

      when( lDanglingVia = axlFormListGetSelItems(ps_DanglingForm1 "ddoViaList")

          axlClearSelSet()      
          axlSetFindFilter( ?enabled'("noall" "vias") ?onButtons '("vias") )
          lVia = nil
          axlVisibleDesign(nil)
          foreach( svia lDanglingVia
            lViaInfo = parseString(svia ",")
            axlVisibleLayer(strcat("via class/" car(lViaInfo)) t)
            axlVisibleLayer(strcat("etch/" car(lViaInfo)) t)
            axlVisibleLayer(strcat("pin/" car(lViaInfo)) t)
            lCoord = parseString(caddr(lViaInfo) " ()")
            fCoordX = atof(car(lCoord))
            fCoordY = atof(cadr(lCoord))
            dVia = car(axlGetSelSet(axlSingleSelectPoint(fCoordX:fCoordY)))
            axlClearSelSet()
            when( dVia
            lVia = cons( dVia lVia)
            )
          )
          axlHighlightObject(lVia)
          axlZoomToDbid(lVia t)   
      )
      );case的第三种情况"ddoViaList"
      ( "ddoShapeList"

      when( lIslandShape = axlFormListGetSelItems(ps_DanglingForm1 "ddoShapeList")

          axlClearSelSet()      
          axlSetFindFilter( ?enabled'("noall" "shapes") ?onButtons '("shapes") )
          lShape = nil
          axlVisibleDesign(nil)
          foreach( shape lIslandShape
            lShapeInfo = parseString(shape ",")
            axlVisibleLayer(strcat("via class/" car(lShapeInfo)) t)
            axlVisibleLayer(strcat("etch/" car(lShapeInfo)) t)
            axlVisibleLayer(strcat("pin/" car(lShapeInfo)) t)
            lCoord = parseString(caddr(lShapeInfo) " ()")
            fCoordX = atof(car(lCoord))
            fCoordY = atof(cadr(lCoord))
            dShape = car(axlGetSelSet(axlSingleSelectPoint(fCoordX:fCoordY)))
            axlClearSelSet()
            when( dShape
            lShape = cons( dShape lShape )
            )
          )
          axlHighlightObject(lShape)
          axlZoomToDbid(lShape t)   
      )
      );case的第四种情况"ddoShapeList"
      ( "ddoLinesDel"
      when( lDanglingLine = axlFormListGetSelItems(ps_DanglingForm1 "ddoLineList")
          axlClearSelSet()      
          axlSetFindFilter( ?enabled'("noall" "clines") ?onButtons '("clines") )   
          lIssueCline = nil
          axlVisibleDesign(nil)
          foreach( sline lDanglingLine
            lTemp = parseString( sline "," )         
            sLayer = car( lTemp )
            lCoord = parseString(caddr(lTemp) " ()to")
            fStartX = atof(car(lCoord))
            fStartY = atof(cadr(lCoord))
            fEndX = atof(caddr(lCoord))
            fEndY = atof(nth(3 lCoord))
            axlVisibleLayer(strcat("etch/" sLayer) t)         
            axlVisibleLayer(strcat("via class/" sLayer) t)
            axlVisibleLayer(strcat("pin/" sLayer) t)      
            sStart = sprintf(nil "x%0.3fy%0.3f" fStartX fStartY)
            sEnd = sprintf(nil "x%0.3fy%0.3f" fEndX fEndY)
            lClines = axlGetSelSet(
                      axlSingleSelectBox(
                        list((fStartX-fFindRange):(fStartY-fFindRange)
                        (fStartX+fFindRange):(fStartY+fFindRange))      
                      ))
            axlClearSelSet()         
            when( lClines
            foreach( cline lClines
                lSeg = cline->segments
                lStartA = car(car(lSeg)->startEnd)
                lEndA = cadr(car(last(lSeg))->startEnd)
                sStartTempA = sprintf( nil "x%0.3fy%0.3f" car(lStartA) cadr(lStartA))
                sEndTempA = sprintf( nil "x%0.3fy%0.3f" car(lEndA) cadr(lEndA))
                lStartB = car(car(last(lSeg))->startEnd)
                lEndB = cadr(car(lSeg)->startEnd)
                sStartTempB = sprintf( nil "x%0.3fy%0.3f" car(lStartB) cadr(lStartB))
                sEndTempB = sprintf( nil "x%0.3fy%0.3f" car(lEndB) cadr(lEndB))
                when( (sStartTempA==sStart && sEndTempA==sEnd) ||
                  (sStartTempA==sEnd && sEndTempA==sStart) ||
                  (sStartTempB==sStart && sEndTempB==sEnd) ||
                  (sStartTempB==sEnd && sEndTempB==sStart)
                  lIssueCline = cons( cline lIssueCline )
                )
            )
            ); end when lClines         
          ); end foreach
          axlDeleteObject(lIssueCline)
          axlFormListDeleteItem(ps_DanglingForm1 "ddoLineList" lDanglingLine)
          axlMsgPut("I- Dangling Line was deleted")
      ); end when dline
      );case的第五种情况"ddoLinesDel"
      ( "ddoViasDel"
      bDRC = axlDBControl('drcEnable nil)
      bShape = axlDBControl( 'dynamicFillMode nil )
      if( lDanglingVia = axlFormListGetSelItems(ps_DanglingForm1 "ddoViaList")then
          axlClearSelSet()      
          axlSetFindFilter( ?enabled'("noall" "vias") ?onButtons '("vias") )
          lVia = nil
          lSys = axlVisibleGet()
          axlVisibleDesign(nil)
          foreach( svia lDanglingVia
            lViaInfo = parseString(svia ",")
            axlVisibleLayer(strcat("via class/" car(lViaInfo)) t)
            lCoord = parseString(caddr(lViaInfo) " ()")
            fCoordX = atof(car(lCoord))
            fCoordY = atof(cadr(lCoord))
            dVia = car(axlGetSelSet(axlSingleSelectPoint(fCoordX:fCoordY)))
            axlClearSelSet()
            when( dVia
            lVia = cons( dVia lVia)
            )
            axlVisibleLayer(strcat("via class/" car(lViaInfo)) nil)
          )
          axlDeleteObject(lVia)
          axlFormListDeleteItem(ps_DanglingForm1 "ddoViaList" lDanglingVia)
          axlMsgPut("I- Dangling Via was deleted")
          axlVisibleSet(lSys)
      else
          axlUIConfirm("E- Pick a item from the list before cilck on Delete button")
      )
      axlDBControl('drcEnable bDRC)      
      axlDBControl( 'dynamicFillMode bShape )   
      );case的第六种情况"ddoViasDel"
      ( "ddoShapesDel"
      axlMsgPut("R- if delete shape on this form is too slow, please use Shape->Delete Islands to delete all island shape and use this tool to double confirm")
      bDRC = axlDBControl('drcEnable nil)
      bShape = axlDBControl( 'dynamicFillMode nil )
      if( lIslandShape = axlFormListGetSelItems(nv_DanglingForm1 "ddoShapeList")then
          axlClearSelSet()      
          axlSetFindFilter( ?enabled'("noall" "shapes") ?onButtons '("shapes") )
          lShape = nil
          lSys = axlVisibleGet()
          axlVisibleDesign(nil)
          foreach( shape lIslandShape
            lShapeInfo = parseString(shape ",")
            axlVisibleLayer(strcat("via class/" car(lShapeInfo)) t)
            axlVisibleLayer(strcat("etch/" car(lShapeInfo)) t)
            axlVisibleLayer(strcat("pin/" car(lShapeInfo)) t)
            lCoord = parseString(caddr(lShapeInfo) " ()")
            fCoordX = atof(car(lCoord))
            fCoordY = atof(cadr(lCoord))
            dShape = car(axlGetSelSet(axlSingleSelectPoint(fCoordX:fCoordY)))
            axlClearSelSet()
            when( dShape
            if( dShape->shapeBoundary then
                ;need to use current dynamic shape and void this island shape
                dVoidPoly=car(axlPolyFromDB(dShape))   ; to be void poly
                dDynaShapePoly=car(axlPolyFromDB(dShape->shapeBoundary)); dynamic shape poly
                dNewPoly= car(axlPolyOperation(dDynaShapePoly dVoidPoly 'ANDNOT)); new shape poly
                sNet = dShape->net->name
                sLayer = dShape->shapeBoundary->layer
                lDynShapeGroup = car(dShape->parentGroups)
                axlDeleteObject(dShape->shapeBoundary); delete original shape
                dNewShape = car(axlDBCreateShape(dNewPoly t sLayer sNet)); create new shape
                dParent=car(car(dNewShape->shapeAuto)->parentGroups)
                axlShapeDynamicUpdate(dNewShape, t) ;update the shape, this is a time causing step            
            else
                lShape = cons( dShape lShape )
            )
            )
            axlVisibleLayer(strcat("etch/" car(lShapeInfo)) nil)
          )
          axlDeleteObject(lShape) ; delete static/whole dynamic shape
          axlFormListDeleteItem(nv_DanglingForm1 "ddoShapeList" lIslandShape)
          axlMsgPut("I- Island Shape was deleted")
          axlVisibleSet(lSys)
          axlFlushDisplay()
      else
          axlUIConfirm("E- Pick a item from the list before cilck on Delete button")
      )
      axlDBControl('drcEnable bDRC)      
      axlDBControl( 'dynamicFillMode bShape )   
      );case的第七种情况"ddoShapesDel"
      ( "ddoClose"
      axlFormClose( ps_DanglingForm1 )
      axlClearSelSet()
      axlFlushDisplay()
      axlEndSkillMode()
      axlMsgPut("Done, Please update DRC and refresh shapes")
      );case的第八种情况"ddoClose"
      ( "ddoAssign"
      bDRC = axlDBControl('drcEnable nil)
      bShape = axlDBControl( 'dynamicFillMode nil )
      if( lDanglingVia = axlFormListGetSelItems(ps_DanglingForm1 "ddoViaList")then
          axlClearSelSet()      
          axlSetFindFilter( ?enabled'("noall" "vias") ?onButtons '("vias") )
          lVia = nil
          lSys = axlVisibleGet()
          axlVisibleDesign(nil)
          foreach( svia lDanglingVia
            lViaInfo = parseString(svia ",")
            axlVisibleLayer(strcat("via class/" car(lViaInfo)) t)
            lCoord = parseString(caddr(lViaInfo) " ()")
            fCoordX = atof(car(lCoord))
            fCoordY = atof(cadr(lCoord))
            dVia = car(axlGetSelSet(axlSingleSelectPoint(fCoordX:fCoordY)))
            axlClearSelSet()
            when( dVia
            lVia = cons( dVia lVia)
            )
            axlVisibleLayer(strcat("via class/" car(lViaInfo)) nil)
          )
          axlMsgPut("I- Select a net by click in the design")
          axlVisibleSet(lSys)

          axlSetFindFilter( ?enabled'("noall" "nets") ?onButtons '("nets") )
          if( axlSingleSelectPoint() then
            sNet = car(axlGetSelSet())->name
            axlClearSelSet()
            foreach( item lVia
            axlDBCloak( 'axlDBCreateVia( item->name item->xy sNet ) 'shape )
            if( item->net->name then
                  sMessage = sprintf( nil "I- Change via net from %s to %s" item->net->name sNet )
            else
                  sMessage = sprintf( nil "I- Change via net from nil to %s" sNet )
            ); end if                     
            axlMsgPut( sMessage )
            )
            axlDeleteObject(lVia)
            axlFormListDeleteItem(ps_DanglingForm1 "ddoViaList" lDanglingVia)
            ;axlMsgPut("I- Dangling Via net was changed")
          else
            axlMsgPut("E- Dummy net was selected, no changes")
          ); end when
      else
          axlUIConfirm("E- Pick a item from the list before cilck on Assign Net button")
      )
      axlDBControl('drcEnable bDRC)      
      axlDBControl( 'dynamicFillMode bShape )
      );case的第九种情况"ddoAssign"
      ( "ddoHelp"
      axlHttp( psmddo_HELPPAGE )
      );case的第十种情况"ddoHelp"
    );end case
);end let
);end procedure

xieeyawen 发表于 2025-2-17 18:24:54

procedure( ps_ddoCheck() ;check主程序
let(
    ( lClines
      lVias
      sNet
      sVia
      lDanglingLine
      bIgnore
      lDanglingVia
      lIslandShape
      sShape
      sLine
    )
    axlClearSelSet()      
    axlSetFindFilter( ?enabled'("noall" "invisible" "clines" ) ?onButtons '("clines" ) )
    lClines = axlGetSelSet(axlAddSelectAll())
    axlClearSelSet()
    axlSetFindFilter( ?enabled'("noall" "invisible""vias") ?onButtons '( "vias") )
    lVias = axlGetSelSet(axlAddSelectAll())
    axlClearSelSet()
    foreach( cline lClines
      when( length(axlDBGetConnect( cline t ))<2
      unless(cline->prop->FILLET||cline->symbolEtch
          if(cline->net then
            sNet = cline->net->name
          else
            sNet = "Dummy"
          )
          sLine = sprintf(nil "%s, %s, %L to %L"
            cadr(parseString(cline->layer "/"))
            sNet
            car(car(cline->segments)->startEnd)
            cadr(car(last(cline->segments))->startEnd)
          )
          lDanglingLine = cons( sLine lDanglingLine )
      )
      )
    )

    lDanglingLine = reverse(sort(lDanglingLine nil))
    foreach( via lVias
      unless( via->symbolEtch ;;; ignore symbol type via
      bIgnore = nil
      if(via->net then
          sNet = via->net->name
          when( rexMatchp("^SNN_" sNet)
            bIgnore = t
          )
      else
          sNet = "Dummy"
      )
      sVia = sprintf( nil "%s, %s, %L"
          cadr(parseString(car(via->startEnd) "/"))
          sNet
          via->xy
      )
      unless( bIgnore
          when( onep(length(axlDBGetConnect( via t )))
            unless( via->testPoint || rexMatchp("_VOID$" via->name )
            lDanglingVia = cons( sVia lDanglingVia )
            )
          )
          when( zerop(length(axlDBGetConnect( via t )))
             lDanglingVia = cons( sVia lDanglingVia )
          ); end when
      ); end unless bIgnore
      ); end unless
    )
    lDanglingVia = reverse(sort(lDanglingVia nil))
    foreach( shape axlDBGetShapes("etch")
      when( length(axlDBGetConnect(shape t))<2
      unless( shape->symbolEtch
          sNet = "Dummy"
          when( shape->net && shape->net->name != ""
            sNet = shape->net->name
          )
          sShape = sprintf(nil "%s, %s, %L"
            cadr(parseString(shape->layer "/"))
            sNet
            car(car(shape->segments)->startEnd)
            )
          lIslandShape = cons( sShape lIslandShape )
      ); end unless
      ); end when
    )
    foreach(net axlDBGetDesign()->nets
      when( net->nBranches > 1
      foreach( branch cdr(net->branches)
          foreach( obj branch->children
            when( obj->objType == "shape"
            sShape = sprintf(nil "%s, %s, %L"
                  cadr(parseString(obj->layer "/"))
                  net->name
                  car(car(obj->segments)->startEnd)
                )
            unless( member( sShape lIslandShape )
                lIslandShape = cons( sShape lIslandShape )
            )
            )
          ); end obj
      ); end branch
      ); end when
    ); end foreach

    lIslandShape = reverse(sort(lIslandShape nil))
    list(lDanglingLine lDanglingVia lIslandShape)
); end let
); end ps_ddoCheck

winskillabc 发表于 2025-2-22 14:30:11

很详细,期待还有更多的代码分析,

xiaomi8 发表于 2025-6-13 09:56:09

厉害了,学习
页: [1]
查看完整版本: quick_danglings.il代码解析form部分