⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 autosilkutils.il

📁 skill语言在Cadence平台二次开发中大量使用
💻 IL
📖 第 1 页 / 共 5 页
字号:
      pbLayer, gap, boundShp, pkgHgt, boundShps, minHgt, airGap, airGap2, sym2, chkObjs, expected, smObjTypeText
      smObjPoly, delShp, drcPt, smObjShp, gapData, actual, txt, drcTxt, drcMsg, drcMsgs, smObjLoc, objPoly, intersectPoly)
  precisionFactor = 10.0 ** ASU_precision
  layer = obj ->layer
  side = ASU_getLayerSide(layer, obj)
  objType = obj ->objType
  bbox = bBoxAdd(obj ->bBox, list(list(-spacing, -spacing) list(spacing, spacing)))
  when(pinChk, smObjTypes = '("PINS"))
  when(viaChk, smObjTypes = cons("VIAS", smObjTypes))
  when(smObjTypes, smObjs = findTypeObjects(smObjTypes, ?bbox bbox))
  when(pinChk && solderedPadsOnlyChk
    smObjs = setof(pin, smObjs
      or(
	pin ->objType == "via"; Check all via pads
	car(pin ->startEnd) == cadr(pin ->startEnd); Check all SMD pads
	cadr(parseString(cadr(pin ->startEnd), "/")) == side; Check only pads on opposite side from leaded device
      )
    )
  )
  when(smShpChk
    smObjTypes = cons("SHAPES", smObjTypes)
    smLayers = list(strcat("BOARD GEOMETRY/SOLDERMASK_", side), strcat("PACKAGE GEOMETRY/SOLDERMASK_", side))
    smObjs = remove(obj, append(smObjs, findTypeObjects("SHAPES", ?layers smLayers ?bbox bbox)))
  )
  case(objType
    ("text"
      text = obj ->text, tempShps = ASU_textToShape(obj, ?quickChk (txtChk == "QUICK"))
      /* Next few lines are for ref desig location checking */
      when(refdesLocChk
	symb = obj ->parent
	class = symb ->component ->class
	when(symb && (symb ->objType == "symbol") && (symb ->refdes == text)
	  tempShp1 = car(if(txtChk == "QUICK", tempShps, ASU_textToShape(obj, ?quickChk t)))
	  pbLayer = strcat("PACKAGE GEOMETRY/PLACE_BOUND_", side)
	  foreach(shp, setof(shp, symb ->children, shp ->layer == pbLayer)
	    gap = caddr(AFn_getAirGap(tempShp1, shp)) || 0
	    when(!airGap || gap < airGap, boundShp = shp, airGap = gap)
	  )
	  pkgHgt = AFn_getProperty(boundShp, "PACKAGE_HEIGHT_MAX")
	  pkgHgt = if(pkgHgt, readstring(pkgHgt), 0)
	  when(airGap && airGap > 0
	    bbox = bBoxAdd(tempShp1 ->bBox, list(list(-airGap, -airGap), list(airGap, airGap)))
	    boundShps = setof(shp, remove(boundShp, findTypeObjects("SHAPES", ?layers pbLayer ?bbox bbox))
	      and(sym2 = shp ->parent, sym2 ->objType == "symbol", sym2 ->component ->class == class))
	    foreach(shp, boundShps
	      minHgt = AFn_getProperty(shp, "PACKAGE_HEIGHT_MIN")
	      minHgt = if(minHgt, readstring(minHgt), 0)
	      gapData = AFn_getAirGap(tempShp1, shp)
	      airGap2 = caddr(gapData) || 0
	      when(airGap2 < airGap && minHgt <= pkgHgt
	        sym2 = shp ->parent
	        actual = round((airGap - airGap2) * precisionFactor) / precisionFactor; round number to precision
	        sprintf(actual, "%g %s", actual, ASU_designUnits)
		sprintf(drcTxt, "%s text ('%s') is %s closer to %s than its own parent symbol", side, text, actual, sym2 ->refdes)
		sprintf(drcMsg, "%s text ('%s') at %L is %s closer to %s than its own parent symbol", side, text, obj ->xy, actual, sym2 ->refdes)
		drcMsgs = cons(drcMsg, drcMsgs)
		drcPt = cadr(gapData) || obj ->xy
		axlDBCreateExternalDRC(drcTxt, drcPt, drcLayer, list(boundShp, obj), sym2 ->xy, actual)
	      )
	    )
	  )
	  unless(txtChk == "QUICK", axlDeleteObject(tempShp1))
	)
	unless(txtChk, axlDeleteObject(tempShps), tempShps = nil)
      )
      /* ************************************************* */
    )
    ("shape", chkObjs = list(obj))
    ("path"
      if(isCallable('axlAirGap) then chkObjs = list(obj)
       else
	foreach(poly, axlPolyFromDB(obj, ?endCapType 'ROUND)
	  tempShps = cons(car(axlDBCreateShape(poly, t, layer)), tempShps)
	)
      )
    )
  )
  sprintf(expected, "%g %s", spacing, ASU_designUnits)
  foreach(tempObj, append(tempShps, chkObjs)
    foreach(soldermaskObj, smObjs
      case(soldermaskObj ->objType
	("pin", smObjTypeText = "Pin Soldermask Pad")
	("via", smObjTypeText = "Via Soldermask Pad")
	("shape", smObjTypeText = "Soldermask Shape")
	(t, "Unexpected Soldermask object")
      )
      if(member(soldermaskObj ->objType, '("pin", "via")) then
	smObjPoly = car(axlPolyFromDB(soldermaskObj, ?layer strcat("PIN/SOLDERMASK_", side), ?padType "REGULAR"))
	delShp = smObjShp = car(axlDBCreateShape(smObjPoly, t, layer))
       else
        unless(isCallable('axlAirGap), smObjPoly = car(axlPolyFromDB(soldermaskObj)))
        delShp = nil, smObjShp = soldermaskObj
      )
      when(smObjShp
	actual = nil
	if(isCallable('axlAirGap) && (objType == "path") then
	  foreach(seg, tempObj ->segments
	    gapData = AFn_getAirGap(seg, smObjShp)
	    airGap = caddr(gapData) || 0.0; axlAirGap returns nil if overlap
	    when(!actual || (airGap < actual), actual = airGap, drcPt = getRectangleCentre(gapData))
	  )
	 else
	  if(isCallable('axlAirGap) then
	    gapData = AFn_getAirGap(tempObj, smObjShp)
	    drcPt = getRectangleCentre(gapData)
	    actual = caddr(gapData) || 0.0; axlAirGap returns nil if overlap
	   else
	    objPoly = car(axlPolyExpand(axlPolyFromDB(tempObj, ?endCapType 'ROUND), spacing, 'ALL_ARC))
	    intersectPoly = car(axlPolyOperation(objPoly, smObjPoly, "AND"))
	    when(intersectPoly
	      gapData = intersectPoly ->bBox
	      drcPt = getRectangleCentre(gapData)
	      actual = caddr(AFn_getAirGap(tempObj, smObjShp)) || 0.0
	    )
	  )
	)
	axlDeleteObject(delShp)
	when(actual
	  actual = round(actual * precisionFactor) / precisionFactor; round number to precision
	  unless(actual >= spacing - axlMKSConvert(0.2, "MILS"); Add a tad to allow for rounding problems
	    actual = if(zerop(actual), "Overlap", sprintf(nil, "%g %s", actual, ASU_designUnits))
	    txt = if(objType == "text", strcat(" ('", text, "')"), "")
	    sprintf(drcTxt, "%s %s%s to %s/req:%s; actual:%s", side, objType, txt, smObjTypeText, expected, actual)
	    sprintf(drcMsg, "%s %s%s to %s/req:%s; actual:%s at %L", side, objType, txt, smObjTypeText, expected, actual, drcPt)
	    drcMsgs = cons(drcMsg, drcMsgs)
	    smObjLoc = soldermaskObj ->xy || car(soldermaskObj ->bBox)
	    axlDBCreateExternalDRC(drcTxt, drcPt, drcLayer, list(obj, soldermaskObj), smObjLoc, actual)
	  )
	)
      )
    )
  )
  axlDeleteObject(tempShps)
  drcMsgs
))

defun( ASU_textToShape (txtObjs @key quickChk, shpLayer, propValue)
 let((layer, tad, text, loc, x0, y0, rot, tbParam, photoWidth, txtHgt, chWid, chSpc, txtLen
      lx, txtLst, txtCh, mergedPolys, unmergedPolys, line, shp, shps, bbox, w, corners, rpath, mergedPoly)
  unless(listp(txtObjs), txtObjs = list(txtObjs))
  tad = axlMKSConvert(0.001, "mm")
  and(shpLayer, !axlIsLayer(shpLayer), axlLayerCreateNonConductor(shpLayer))
  foreach(obj, txtObjs
    layer = shpLayer || obj ->layer
    text = obj ->text, loc = obj ->xy, x0 = car(loc), y0 = cadr(loc), rot = -obj ->rotation
    tbParam = axlGetParam(strcat("paramTextBlock:" obj ->textBlock))
    photoWidth = tbParam ->photoWidth
    when(zerop(photoWidth), photoWidth = tad)
    txtHgt = tbParam ->height, chWid = tbParam ->width, chSpc = tbParam ->charSpace
    txtLen = strlen(text) * (tbParam ->width + chSpc) - chSpc
    when(obj ->isMirrored, txtLen = -txtLen, chWid = -chWid, chSpc = -chSpc)
    lx = case(obj ->justify, ("LEFT", x0), ("CENTER", x0 - txtLen / 2.0), ("RIGHT", x0 - txtLen))
    txtLst = parseString(text, "")
    while(txtLst
      txtCh = car(txtLst), txtLst = cdr(txtLst)
      mergedPolys = unmergedPolys = nil
      foreach(pts, ASU_getChLines(txtCh, chWid, txtHgt, lx, y0)
	if(quickChk then bbox = ASU_getLinesBbox(pts, bbox), mergedPolys = t
         else
          unless(zerop(rot), pts = rotatePoints(pts, rot, loc))
	  line = caar(axlDBCreateLine(pts, photoWidth, layer))
	  foreach(poly, axlPolyFromDB(line, ?endCapType 'ROUND)
	    mergedPoly = axlPolyOperation(mergedPolys, poly, 'or)
	    ; Polys with isHole == t might occur.
	    ;A bug with axlPolyOperation appears to have this affect sometimes.
	    if(mergedPoly && !member(t, mergedPoly ~>isHole)
	     then mergedPolys = mergedPoly
	     else unmergedPolys = cons(poly, unmergedPolys)
	    )
	  )
	  axlDeleteObject(line)
	)
      )
      unless(quickChk
	foreach(poly, append(mergedPolys, unmergedPolys)
	  if(poly ->isHole ; This shouldn't occur. A bug with axlPolyOperation appears to have this affect sometimes.
	   then shp = car(axlDBCreateRectangle(poly ->bBox, t, layer))
	   else shp = car(axlDBCreateShape(poly, t, layer))
	  )
	  when(shp
	    when(propValue, AFn_addProperty(shp, "TEXTSHAPE", propValue))
	    shps = cons(shp, shps)
	  )
	)
      )
      lx = lx + chWid + chSpc
    )
  )
  when(quickChk
    w = photoWidth / 2.0
    bbox = list(list(caar(bbox) - w, cadar(bbox) - w), list(caadr(bbox) + w, cadadr(bbox) + w))
    if(orthogonalp(rot) then
      unless(zerop(rot), bbox = rotatePoints(bbox, rot, loc))
      shp = car(axlDBCreateRectangle(bbox, t, layer))
     else
      corners = list(car(bbox), list(caar(bbox), cadadr(bbox)), cadr(bbox), list(caadr(bbox), cadar(bbox)), car(bbox))
      corners = rotatePoints(corners, rot, loc)
      rpath = axlPathStart(corners)
      shp = car(axlDBCreateShape(rpath, t, layer))
    )
    when(propValue, AFn_addProperty(shp, "TEXTSHAPE", propValue))
    shps = list(shp)
  )
  shps
))

defun( ASU_getLinesBbox (pts, bbox)
 let((lx, ly, rx, uy)
  if(bbox
   then lx = caar(bbox), ly = cadar(bbox), rx = caadr(bbox), uy = cadadr(bbox)
   else lx = rx = caar(pts), ly = uy = cadar(pts), pts = cdr(pts)
  )
  foreach(pt, pts, lx = min(lx, car(pt)), ly = min(ly, cadr(pt)), rx = max(rx, car(pt)), uy = max(uy, cadr(pt)))
  list(lx:ly, rx:uy)
))

defun( ASU_getChLines (txtCh, chWid, txtHgt, lx, ly)
 let((lines, lineList, result)
  lines = case(txtCh
    ("\"", '(((0.567 0.783) (0.65 1.0)) ((0.433 1.0) (0.35 0.783))))
    ("#", '(((0.0 0.5) (1.0 0.5)) ((1.0 0.167) (0.0 0.167)) ((0.5 -0.333) (0.833 1.0)) ((0.5 1.0) (0.167 -0.333))))
    ("$", '(((0.333 1.0) (0.333 -0.333)) ((0.667 -0.333) (0.667 1.0)) ((1.0 0.567) (1.0 0.667) (0.833 0.833) (0.167 0.833) (0.0 0.667) (0.0 0.5) (0.167 0.333) (0.833 0.333) (1.0 0.167) (1.0 0.0) (0.833 -0.167) (0.167 -0.167) (0.0 0.0) (0.0 0.1))))
    ("%", '(((0.8 0.333) (0.9 0.3) (0.95 0.25) (0.983 0.15) (0.95 0.05) (0.9 0.0) (0.8 -0.033) (0.7 0.0) (0.65 0.05) (0.617 0.15) (0.65 0.25) (0.7 0.3) (0.8 0.333)) ((0.2 1.0) (0.3 0.967) (0.35 0.917) (0.383 0.817) (0.35 0.717) (0.3 0.667) (0.2 0.633) (0.1 0.667) (0.05 0.717) (0.017 0.817) (0.05 0.917) (0.1 0.967) (0.2 1.0)) ((0.8 1.0) (0.2 -0.033))))
    ("&", '(((1.0 0.0) (0.667 -0.333) (0.167 -0.333) (0.0 -0.167) (0.0 0.167) (0.167 0.333) (0.5 0.5) (0.667 0.667) (0.667 0.833) (0.5 1.0) (0.333 1.0) (0.167 0.833) (0.167 0.667) (1.0 -0.333))))
    ("'", '(((0.667 0.875) (0.542 0.875) (0.542 1.0) (0.667 1.0) (0.667 0.875) (0.5 0.667))))
    ("(", '(((0.417 1.0) (0.25 0.833) (0.167 0.667) (0.167 0.0) (0.25 -0.167) (0.417 -0.333))))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -