作者 主題: SKILL程式,POLYGON或RECTANGLE挖SLOT(終篇)  (閱讀 4306 次)

0 會員 與 1 訪客 正在閱讀本文。

lkkl

  • 活潑的大學生
  • ***
  • 文章數: 431
    • 檢視個人資料
    • 我的線上小窩
修正一些BUG,修改->挖slot挖中間,可輸入對話框,下拉式選單
這有圖
http://www.taconet.com.tw/lkkllkkl/skill2.html

代碼: [選擇]
/*
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 作者:Y.P.LIN
 檔名: CUT.il
 用途: LAYOUT輔助工具
 日期: 2007.12.11
 版本: 正式版1.00
 用法:在icfb,load本sKILL(例如 load "CUT.il" ),再開一個layout,視窗上多一個選單,選取rectangle(可複選),
      選LAYOUT-TOOLS,再選SLOT,會跳出輸入框,在按OK(挖slot面積大時可能要等待一些時間)
 參考:雷奧星空論壇(http://www.armbell.com/forum/viewforum.php?f=13&mforum=iclayout)
     :中国集成电路教育网(http://www.icedu.net/Article/shuzi/houduan/Index.html)
     :google搜尋
     :cadence手冊(安裝目錄下/doc/sk開頭目錄)
 注 :本SKILL還在開發中,目前功能
     1.切RECTANGLE的4個角     
     2.polygon的90度角都可切
     3.挖SLOT
 聲明:1.程式著作為OPEN SOURCE,歡迎做任何修改,但"參考"不得做更動
      2.SKILL為CANDENCE所有
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
*/
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;快速鍵;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;hiSetBindKey("Layout" "None<Btn2Down>" "trSimpleMenu()");設定快速鍵為滑鼠中鍵(Layout視窗有效)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;把polygon切成rectangle&&挖slot;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;注意切開一定要從右向左切(因為左邊會保持原來SHAPE_ID);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
procedure(getrec(obj)                                              ;切rectangle程序
      let((list_xy getshape_point sort_point a_sort_point          ;宣告local變數
           cut_line rec_get type xyBox y1 y2) 
           type=obj~>objType
   if(equal(type "polygon") then
            xyBox=obj~>bBox                               ;取得shape的BOX
                    y1 = cadr(car(xyBox))                          ;最小y
                    y2 = cadr(cadr(xyBox))                         ;最大y
                    getshape_point=obj~>points                     ;取得每個角的點(pologon)是一組list
            sort_point=sortcar(getshape_point 'lessp)      ;根據第1項排序
            a_sort_point = reverse( sort_point )           ;反轉list
                    foreach(list_xy a_sort_point                   ;把點的list逐一丟入變數list_xy
            x=car(list_xy)                                 ;取得x
    cut_line=list((x:y1) (x:y2))                   ;垂直線
                    rec_get= leChopShape( shape cut_line nil nil ) ;根據x垂直切開(右邊是一定是rectangle)
    slot_rec(rec_get)                        ;
                    );foreach
    );if
           if(equal(type "rect") then                              ;rect
           slot_hole(obj)
   );if
        );let
      );procedure
procedure(slot_rec(obj)                                            ;slot
let((shape type)
   foreach(shape obj
   type=shape~>objType                                             ;取得物件型態
    if(equal(type "rect") then                                     ;是rectangle才挖slot
      slot_hole(shape);
      );if
  );foreach
  );let
)

procedure(slot_hole(rect_shape)                                            ;挖洞
let((slotx sloty pitchx pitchy slot_width slot_heigh xint yint             ;local變數
    slot_pitchx slot_pitchy x1 y1 x2 y2 withx heighy x0 y0 slot_list)
;slot_width=5                                                               ;slot的長
;slot_heigh=2                                                               ;slot的高
;slot_pitchx=15                                                             ;slot的pitch
;slot_pitchy=12                                                             ;slot的pitch
slot_width=slotForm->slot_widthID->value                              ;取得輸入框的值
slot_heigh=slotForm->slot_heighID->value
slot_pitchx=slotForm->slot_width_pitchID->value
slot_pitchy=slotForm->slot_heigh_pitchID->value
xyBox=rect_shape~>bBox                                                     ;取得BOX
     x1 = car(car(xyBox))
     y1 = cadr(car(xyBox))
     x2 = car(cadr(xyBox))
     y2 = cadr(cadr(xyBox))
withx=x2-x1                                                                ;矩型長
heighy=y2-y1                                                               ;矩型寬
if(heighy > withx then                                                     ;判定往y軸較長(設定挖的距離,pitch)
slotx=slot_heigh
sloty=slot_width
pitchx=slot_pitchy
pitchy=slot_pitchx
y1=y1+int((heighy-int(heighy/pitchy)*pitchy)/2+(pitchy-sloty)/2)            ;y1+(被除數-商X除數)/2[目的是挖在中間]
x1=x1+int((withx-int(withx/pitchx)*pitchx)/2+(pitchx-slotx)/2)              ;x1+(被除數-商X除數)/2[目的是挖在中間]
else
slotx= slot_width                                                          ;x軸較長(挖x較長)
sloty=slot_heigh
pitchx=slot_pitchx
pitchy=slot_pitchy
y1=y1+int((heighy-int(heighy/pitchy)*pitchy)/2+(pitchy-sloty)/2)            ;y1+(被除數-商X除數)/2[目的是挖在中間記得轉整數(OFFGRIDE)]
x1=x1+int((withx-int(withx/pitchx)*pitchx)/2+(pitchx-slotx)/2)              ;x1+(被除數-商X除數)/2[目的是挖在中間]
);if


xint=x1                                                                       ;開始的x座標
yint=y1                                                                       ;開始的y座標
while(y1+(pitchy-sloty)/2+sloty <= y2                                                ;當y還未超過box
    y0=y1
    y1=y1+pitchy                                                              ;加上pitch
    while(x1+(pitchx-slotx)/2+slotx <= x2                                            ;當x還未超過box
     x0=x1                                                 
     x1=x1+pitchx
     slot_list=list((x0:y0) (x0+slotx:y0) (x0+slotx:y0+sloty) (x0:y0+sloty))
     leChopShape( rect_shape slot_list  t t)
    );while
   x1=xint                                                                    ;重設x1
   );while
   y1=yint
   );let
)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;list((0 0) (1 1) .........)轉成布林lis(t t ....);;;;;;;;;;;;;;;;
procedure(contains_even(list)
      prog( ()
          result=list()
          foreach(element list
          if(element != nil
  result = cons( t result )
            )
            ) /* end foreach */
           return(result)
) /* end prog */
) /* end contains_pass */
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cut矩型的4個角;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
procedure(cut(xyBox)                                                  ;取得四邊行CUT點座標的程序
let((d x1 x2 y y2 cut1 cut2 cut3 cut4)
d=cutForm->cutID->value                                               ;取得輸入框的值(切的距離)
x1 = car(car(xyBox))                                   
y1 = cadr(car(xyBox))
x2 = car(cadr(xyBox))
y2 = cadr(cadr(xyBox))
cut1=list((x1:y1) (x1+d:y1) (x1:y1+d) (x1:y1))                        ;cut lin1座標list(是一個封閉cycle)
cut2=list((x2:y1) (x2-d:y1) (x2:y1+d) (x2:y1))                        ;cut lin2座標list(是一個封閉cycle)
cut3=list((x1:y2) (x1+d:y2) (x1:y2-d) (x1:y2))                        ;cut lin3座標list(是一個封閉cycle)
cut4=list((x2:y2) (x2-d:y2) (x2:y2-d) (x2:y2))                        ;cut lin4座標list(是一個封閉cycle)
leChopShape( shape cut1  t t)                                         ;cut一邊,第一個t只是一個封閉cycle,第2個t指移除(remove)
leChopShape( shape cut2  t t)                                         ;cut一邊
leChopShape( shape cut3  t t)                                         ;cut一邊
leChopShape( shape cut4  t t)                                         ;cut一邊
);let
)

procedure(cut_rectangle()
  let((selobj type selobjbox)
  cutForm()
  selobj=geGetSelSet()                                 ;取得選的物件
  foreach(shape selobj                                 ;把每一個物件逐一丟到shape變數
          type=shape~>objType                          ;取得物件型態
  if(equal(type "rect") then                   ;判定rectangle
          selobjbox=shape~>bBox                        ;取得物件的BOX(指方形座標2點->list)
          cut(selobjbox);                              ;呼叫cut程序,且給一個參數selobjx
  );endif
         );foreach
  );let
 );procedure
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;切polygon的角;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
procedure(chop()
let((selobj type l_selArray)
   cutForm()
   d=cutForm->cutID->value                             ;取得輸入框的值
   selobj=geGetSelSet()                                ;取得選的物件
   foreach(shape selobj                                ;把每一個物件逐一丟到shape變數
   type=shape~>objType                                 ;取得物件型態
   if(equal(type "polygon") then                       ;判定polygon (注意rectangle無法用~>points取點)
   getshape_point_list=shape~>points                   ;取得每個角的點(pologon)是一組list
   l_selArray= contains_even(getshape_point_list)      ;把上面取得點轉成布林list
   leModifyCorner( shape l_selArray t d )              ;切角的函數l_seArray指布林list[list(t t ....)],t指chamer[或nil]
   );endif
   );foreach
   );let
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;挖slot;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
procedure(slotget()
 let((selobj shape slot_width slot_heigh slot_pitchx slot_pitchy)
   slotFormget()
   slot_width=slotForm->slot_widthID->value                              ;取得輸入框的值
   slot_heigh=slotForm->slot_heighID->value
   slot_pitchx=slotForm->slot_width_pitchID->value
   slot_pitchy=slotForm->slot_heigh_pitchID->value
   if((slot_pitchy > slot_heigh+5)&&(slot_pitchx > slot_width+5) then
   selobj=geGetSelSet()                                  ;取得選的物件
    foreach(shape selobj                                 ;把每一個物件逐一丟到shape變數
     getrec(shape)
     );foreach
     else
     waring()
     )
     );let
    );procedure


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;表單;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
trA_MenuItem = hiCreateMenuItem(                          ;menu項目
   ?name 'trA_MenuItem
   ?itemText "cut_rectangle"                              ;menu項目標題
   ?callback "cut_rectangle()" ;;; prints B in the CIW    ;選項後的動作(呼叫cut_rectangle()程序)
   )
trB_MenuItem = hiCreateMenuItem(                          ;menu項目
   ?name 'trB_MenuItem
   ?itemText "chop_any_polygon"                           ;menu項目標題
   ?callback "chop()" ;;; prints B in the CIW             ;選項後的動作(呼叫chop()程序)
    )

trC_MenuItem = hiCreateMenuItem(                          ;menu項目
   ?name 'trC_MenuItem
   ?itemText "SLOT"                                       ;menu項目標題
   ?callback  "slotget()"                                    ;選項後的動作(呼叫slotget()程序)
    )

trD_MenuItem = hiCreateMenuItem(                          ;menu項目
   ?name 'trD_MenuItem
   ?itemText "About"                                ;menu項目標題
   ?callback  "about()"                             ;選項後的動作(在CIW視窗印出Hello World!!)
   )

;;; creating the reminder list
procedure(about()
trReminders = '( "PRODUTS:Y.P.LIN" )
foreach( reminderText trReminders ; for each reminder
   hiDisplayAppDBox(
       ?name      gensym( 'trReminderDialogBox ) ; unique variable
       ?dboxBanner "about.."
       ?dboxText reminderText
       ?callback print( "OK" ) ; dynamically built callback
       ?dialogType hicWarningDialog
       ?dialogStyle 'modeless
       ?buttonLayout 'YesNo
        )
       ) ; foreach
       printf( "%s completed" trReminders )
)
procedure(waring()
trReminders = "Waring!! pitch must is longer than slot"
 hiDisplayAppDBox(
       ?name      gensym( 'trReminderDialogBox ) ; unique variable
       ?dboxBanner "about.."
       ?dboxText trReminders
       ?callback print( "OK" ) ; dynamically built callback
       ?dialogType hicWarningDialog
       ?dialogStyle 'modeless
       ?buttonLayout 'YesNo
           )
       printf( "%s completed" trReminders )
);procedure

;procedure(trSimpleMenu()                                ;產生meun表單的程序
; let((simpleMenuID)                                     ;宣告區域(local)變數
; word="Hello wodr!!"                                    ;字串變數
; simpleMenuID=hiCreateMenu(                             ;產生一個menu
; 'simpleMenu                                            ;GLOBAL(ID)
; "LAYOUT TOOLS"                                          ;標題
; '(trA_MenuItem trB_MenuItem trC_MenuItem trD_MenuItem) ;LIST(表單的項目)
; )

; hiDisplayMenu(simpleMenuID)                            ;根據menuID在螢幕顯示
;);let
;);proce

hiCreatePulldownMenu(
'usrPulldownMenu
"LAYOUT-TOOLS"
list(trA_MenuItem trB_MenuItem trC_MenuItem trD_MenuItem)
)
procedure(InsertBannerMenu(lViewProp)
wCellView = getq(lViewProp window)
hiInsertBannerMenu(
wCellView
'usrPulldownMenu
length( hiGetBannerMenus(wCellView))
)
)
deRegUserTriggers(
"maskLayout"
nil
nil
'InsertBannerMenu
)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;slot輸入框;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure slotFormget()
 (prog (slot_widthID slot_heighID slot_width_pitchID slot_heigh_pitchID slotFormID)

slot_widthID=hiCreateIntField(
        ?name 'slot_widthID
        ?prompt "slot width  distance(5~100) :"
        ?value 20
        ?defValue 20
        ?range (range 5 100)
;?editable nil
)
slot_heighID=hiCreateIntField(
        ?name 'slot_heighID
        ?prompt "slot heigh distance(1~5) :"
        ?value 2
        ?defValue 2
        ?range (range 1 5)
        ;?editable nil
)
slot_width_pitchID=hiCreateIntField(
       ?name 'slot_width_pitchID
       ?prompt "slot width picth(>slot width distancr)(15~110) :"
       ?value 30
       ?defValue 30
       ?range (range 15 110)
       ;?editable nil
)

slot_heigh_pitchID=hiCreateIntField(
      ?name 'slot_heigh_pitchID
      ?prompt "slot heigh picth(>slot heigh distancr)(6~36) :"
      ?value 10
      ?defValue 10
      ?range (range 6 36)
      ;?editable nil
  )

slotFormID=hiCreateForm(
    'slotForm
    "LAYOUT SLOT"
    (list "()")
list(   
    (list slot_widthID 0:20 520:30 320)
    (list slot_heighID 0:50 520:30 320 )
    (list slot_width_pitchID 0:80 520:30 320 )
    (list slot_heigh_pitchID 0:110 520:30 320 )
   )
   nil nil
)

(hiDisplayForm slotFormID)

);prog
);proc


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cut(chop)輸入框;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(procedure cutForm()
 (prog (cutID)

cutID=hiCreateFloatField(
        ?name 'cutID
        ?prompt "cut distance :"
        ?value .5
        ?defValue .5
        ?range (range .1 100.0)
        ;?editable nil
)

cutFormID=hiCreateForm(
    'cutForm
     "LAYOUT CUT(or CHOP) distance"
    (list "(cut)")
     list(
          (list cutID 0:20 320:30 120)
         )
        nil nil
      )
  (hiDisplayForm cutFormID)
  );prog
 );proc



/*
/////////////////////////////////////////////////
Thanks for your enjoy!!
////////////////////////////////////////////////
*/

愛護地球請用LINUX,省電又環保,大家共同為地球盡一份心力.
小弟的網頁
http://yplin123.googlepages.com/home
"資訊人權貴" 之家(令人佩服的洪朝貴老師)
http://people.ofset.org/~ckhung/

jling

  • 可愛的小學生
  • *
  • 文章數: 1
    • 檢視個人資料
回覆: SKILL程式,POLYGON或RECTANGLE挖SLOT(終篇)
« 回覆 #1 於: 2009-08-11 16:31 »
您好!
我之前自己编写了一个挖slot的脚本,然后经常会报错invalid shape,比如:“*Error* lefChopShape: Invalid shape – db:198056400”;
后来在网上看到你这篇帖子,然后load你的cut.il脚本,选多个rectangle,也会报同样的错,试了很久都不知道是什么原因;
请问你有碰到过这种情况吗?怎么解决呢?

其中有一点我更是不明白,明明我们脚本里用的事leChopShape函数,可是为什么报错里边是“lefChopShape”,这个lefChopShape是什么呢?跟leChopShape是什么关系?唉,望有人一起讨论啊。。。