master
John Lauer Publish 1.10.8 ab573aa 2mo ago
[
  {
    "modelPath": "C:/tmp/LAN7800.step",
    "orient": true,
    "pin1": [
      -3.5,
      2.75
    ],
    "layersOff": [],
    "task": "Demo_Board",
    "name": "LAN7800_3d",
    "script": "import adsk.core, adsk.fusion, math\napp=adsk.core.Application.get(); doc=app.activeDocument\nd=adsk.fusion.Design.cast(app.activeProduct); root=d.rootComponent\nim=app.importManager\nim.importToTarget(im.createSTEPImportOptions('C:/tmp/LAN7800.step'), root)\noc=root.occurrences.item(root.occurrences.count-1); bb=oc.boundingBox\ndx=bb.maxPoint.x-bb.minPoint.x; dy=bb.maxPoint.y-bb.minPoint.y; dz=bb.maxPoint.z-bb.minPoint.z\nthin=min(dx,dy,dz); big=max(dx,dy,dz)\ntall_z=(dz>=dx and dz>=dy)\nis_flat=(thin < 0.5*big)\naxis=None\nif is_flat and not tall_z:\n axis=(1,0,0) if (dy<=dx and dy<=dz) else ((0,1,0) if (dx<=dy and dx<=dz) else None)\nif axis:\n mat=oc.transform2.copy(); r=adsk.core.Matrix3D.create()\n r.setToRotation(math.pi/2, adsk.core.Vector3D.create(*axis), adsk.core.Point3D.create(0,0,0))\n mat.transformBy(r); oc.transform2=mat\nPIN1=(-0.35, 0.275)\nPIN1_SKIP=None\nres_pin1={'pad1_mm': [-3.5,2.75], 'mark_mm': None, 'rotatedDeg': 0, 'status': 'unchecked'}\ndef _mark(occ):\n    bb2=occ.boundingBox; zmax=bb2.maxPoint.z; best=None\n    def _w(comp, depth):\n        nonlocal best\n        if depth>6: return\n        for i in range(comp.bRepBodies.count):\n            b=comp.bRepBodies.item(i)\n            try: vol=b.volume\n            except Exception: vol=0\n            if vol*1000 < 5: continue\n            for e in b.edges:\n                try:\n                    g=e.geometry\n                    if g.objectType not in (adsk.core.Circle3D.classType(), adsk.core.Arc3D.classType()): continue\n                    c=g.center\n                    if abs(c.z-zmax)>0.03 or g.radius>0.1: continue\n                    score=abs(c.x)+abs(c.y)\n                    if best is None or score>best[0]: best=(score,c.x,c.y)\n                except Exception: pass\n        for j in range(comp.occurrences.count): _w(comp.occurrences.item(j).component, depth+1)\n    _w(occ.component, 0)\n    return None if best is None else (best[1],best[2])\ntry:\n    mk=_mark(oc)\n    if mk: res_pin1['mark_mm']=[round(mk[0]*10,2), round(mk[1]*10,2)]\n    if mk and PIN1:\n        import math as _m\n        want=_m.atan2(PIN1[1],PIN1[0]); have=_m.atan2(mk[1],mk[0])\n        k=int(round(((want-have)/(_m.pi/2)))) % 4\n        if k:\n            mat=oc.transform2.copy(); r=adsk.core.Matrix3D.create()\n            r.setToRotation(k*_m.pi/2, adsk.core.Vector3D.create(0,0,1), adsk.core.Point3D.create(0,0,0))\n            mat.transformBy(r); oc.transform2=mat\n            res_pin1['rotatedDeg']=k*90\n        res_pin1['status']='rotated' if k else 'aligned'\n    elif PIN1: res_pin1['status']='no_mark_on_chip'\n    else: res_pin1['status']='no_pad1_in_lbr'\nexcept Exception as _e: res_pin1['status']='error: '+str(_e)[:80]\nif PIN1_SKIP: res_pin1['status']=PIN1_SKIP\ntry:\n app.activeViewport.fit()\nexcept: pass\ndef _sub(p,nm):\n import time as _ts\n for _try in range(4):\n  for i in range(p.dataFolders.count):\n   if str(p.dataFolders.item(i).name).lower()==str(nm).lower(): return p.dataFolders.item(i)\n  try: return p.dataFolders.add(nm)\n  except Exception as _fe:\n   if 'CB_NAE' not in str(_fe) and 'same name' not in str(_fe): raise\n   adsk.doEvents(); _ts.sleep(2.0)\n raise RuntimeError('cloud folder %s exists but cannot be resolved' % nm)\nres={}\nnames=[]; hidden=[]\ndef _layer(n):\n    n=(n or '').split(':')[0]\n    return n.startswith('Adom.') and n in LAYERS_OFF\ndef _walk(comp, group, hide):\n    for i in range(comp.bRepBodies.count):\n        b=comp.bRepBodies.item(i); names.append((group or '')+'/'+b.name)\n        if hide or _layer(b.name):\n            try:\n                b.isLightBulbOn=False; hidden.append((group or '')+'/'+b.name)\n            except Exception: pass\n    for j in range(comp.occurrences.count):\n        o=comp.occurrences.item(j); on=(o.component.name or o.name).split(':')[0]\n        g=group or (on if on.startswith('Adom.') else '')\n        h=hide or _layer(on)\n        if h and not hide:\n            try: o.isLightBulbOn=False\n            except Exception: pass\n        _walk(o.component, g, h)\nLAYERS_OFF=set([])\ntry:\n    _walk(oc.component, '', False)\nexcept Exception as _e:\n    res['layersError']=str(_e)[:120]\nres['bodies']=names; res['layersHidden']=hidden\nres['pin1']=res_pin1\nres['placement']=globals().get('PLACEMENT_RES')\nproj=None\ntry: proj=app.data.activeProject\nexcept Exception as e: res['projErr']=str(e)[:60]\nif not proj:\n try:\n  hubs=app.data.dataHubs\n  for hi in range(hubs.count):\n   ps=hubs.item(hi).dataProjects\n   for pj2 in range(ps.count):\n    p2=ps.item(pj2)\n    ok=False\n    try: ok=(p2.id=='a.YnVzaW5lc3M6YWRvbTMjMjAyMzExMjk3MDM5NjAzMzE')\n    except Exception: ok=False\n    if not ok:\n     try: ok=(p2.name=='Main')\n     except Exception: continue\n    if ok: proj=p2; break\n   if proj: break\n except Exception as e: res['projErr']=str(e)[:60]\nif not proj:\n try:\n  hubs=app.data.dataHubs\n  for hi in range(hubs.count):\n   ps=hubs.item(hi).dataProjects\n   for pj2 in range(ps.count):\n    try:\n     p2=ps.item(pj2); p2.rootFolder\n     proj=p2; break\n    except Exception: continue\n   if proj: break\n  if not proj:\n   for hi in range(hubs.count):\n    try:\n     proj=hubs.item(hi).dataProjects.add('Adom'); break\n    except Exception as e: res['createErr']=str(e)[:60]\n except Exception as e: res['projErr2']=str(e)[:60]\nif not proj: res['errorCode']='no_cloud_project'\ntry:\n if proj is None: raise RuntimeError('no usable cloud project on this account')\n rf=proj.rootFolder\n wsf=_sub(_sub(rf,'Adom AI Workspace'),'Demo_Board')\n try:\n  doc.saveAs('LAN7800_3d', wsf, '3d package (footprint+chip)', '')\n except Exception as _se:\n  if 'CB_NAE' in str(_se) or 'same name' in str(_se):\n   import time as _t0; _nm='LAN7800_3d-'+_t0.strftime('%m%d%H%M%S')\n   doc.saveAs(_nm, wsf, '3d package (footprint+chip)', ''); res['renamedTo']=_nm\n  else: raise\n import time as _tt\n fid=None\n for w in range(40):\n  try: fid=doc.dataFile.id if doc.dataFile else None\n  except Exception: fid=None\n  if fid and 'dm.lineage:' in str(fid): break\n  adsk.doEvents(); _tt.sleep(1.5)\n res['path']=fid\n res['dims']=[round(dx*10,2),round(dy*10,2),round(dz*10,2)]\nexcept Exception as e: res['err']=str(e)[:80]\nresult=res\n"
  },
  {
    "modelPath": "C:/x/y z/chip.step",
    "orient": false,
    "pin1": null,
    "layersOff": [
      "Adom.SolderBalls",
      "Adom.Board"
    ],
    "task": "AI 3D packages",
    "name": "chip_3d",
    "script": "import adsk.core, adsk.fusion, math\napp=adsk.core.Application.get(); doc=app.activeDocument\nd=adsk.fusion.Design.cast(app.activeProduct); root=d.rootComponent\nim=app.importManager\nim.importToTarget(im.createSTEPImportOptions('C:/x/y z/chip.step'), root)\noc=root.occurrences.item(root.occurrences.count-1); bb=oc.boundingBox\ndx=bb.maxPoint.x-bb.minPoint.x; dy=bb.maxPoint.y-bb.minPoint.y; dz=bb.maxPoint.z-bb.minPoint.z\nPIN1=None\nPIN1_SKIP='skipped_orient_false'\nres_pin1={'pad1_mm': None, 'mark_mm': None, 'rotatedDeg': 0, 'status': 'unchecked'}\ndef _mark(occ):\n    bb2=occ.boundingBox; zmax=bb2.maxPoint.z; best=None\n    def _w(comp, depth):\n        nonlocal best\n        if depth>6: return\n        for i in range(comp.bRepBodies.count):\n            b=comp.bRepBodies.item(i)\n            try: vol=b.volume\n            except Exception: vol=0\n            if vol*1000 < 5: continue\n            for e in b.edges:\n                try:\n                    g=e.geometry\n                    if g.objectType not in (adsk.core.Circle3D.classType(), adsk.core.Arc3D.classType()): continue\n                    c=g.center\n                    if abs(c.z-zmax)>0.03 or g.radius>0.1: continue\n                    score=abs(c.x)+abs(c.y)\n                    if best is None or score>best[0]: best=(score,c.x,c.y)\n                except Exception: pass\n        for j in range(comp.occurrences.count): _w(comp.occurrences.item(j).component, depth+1)\n    _w(occ.component, 0)\n    return None if best is None else (best[1],best[2])\ntry:\n    mk=_mark(oc)\n    if mk: res_pin1['mark_mm']=[round(mk[0]*10,2), round(mk[1]*10,2)]\n    if mk and PIN1:\n        import math as _m\n        want=_m.atan2(PIN1[1],PIN1[0]); have=_m.atan2(mk[1],mk[0])\n        k=int(round(((want-have)/(_m.pi/2)))) % 4\n        if k:\n            mat=oc.transform2.copy(); r=adsk.core.Matrix3D.create()\n            r.setToRotation(k*_m.pi/2, adsk.core.Vector3D.create(0,0,1), adsk.core.Point3D.create(0,0,0))\n            mat.transformBy(r); oc.transform2=mat\n            res_pin1['rotatedDeg']=k*90\n        res_pin1['status']='rotated' if k else 'aligned'\n    elif PIN1: res_pin1['status']='no_mark_on_chip'\n    else: res_pin1['status']='no_pad1_in_lbr'\nexcept Exception as _e: res_pin1['status']='error: '+str(_e)[:80]\nif PIN1_SKIP: res_pin1['status']=PIN1_SKIP\ntry:\n app.activeViewport.fit()\nexcept: pass\ndef _sub(p,nm):\n import time as _ts\n for _try in range(4):\n  for i in range(p.dataFolders.count):\n   if str(p.dataFolders.item(i).name).lower()==str(nm).lower(): return p.dataFolders.item(i)\n  try: return p.dataFolders.add(nm)\n  except Exception as _fe:\n   if 'CB_NAE' not in str(_fe) and 'same name' not in str(_fe): raise\n   adsk.doEvents(); _ts.sleep(2.0)\n raise RuntimeError('cloud folder %s exists but cannot be resolved' % nm)\nres={}\nnames=[]; hidden=[]\ndef _layer(n):\n    n=(n or '').split(':')[0]\n    return n.startswith('Adom.') and n in LAYERS_OFF\ndef _walk(comp, group, hide):\n    for i in range(comp.bRepBodies.count):\n        b=comp.bRepBodies.item(i); names.append((group or '')+'/'+b.name)\n        if hide or _layer(b.name):\n            try:\n                b.isLightBulbOn=False; hidden.append((group or '')+'/'+b.name)\n            except Exception: pass\n    for j in range(comp.occurrences.count):\n        o=comp.occurrences.item(j); on=(o.component.name or o.name).split(':')[0]\n        g=group or (on if on.startswith('Adom.') else '')\n        h=hide or _layer(on)\n        if h and not hide:\n            try: o.isLightBulbOn=False\n            except Exception: pass\n        _walk(o.component, g, h)\nLAYERS_OFF=set(['Adom.Board', 'Adom.SolderBalls'])\ntry:\n    _walk(oc.component, '', False)\nexcept Exception as _e:\n    res['layersError']=str(_e)[:120]\nres['bodies']=names; res['layersHidden']=hidden\nres['pin1']=res_pin1\nres['placement']=globals().get('PLACEMENT_RES')\nproj=None\ntry: proj=app.data.activeProject\nexcept Exception as e: res['projErr']=str(e)[:60]\nif not proj:\n try:\n  hubs=app.data.dataHubs\n  for hi in range(hubs.count):\n   ps=hubs.item(hi).dataProjects\n   for pj2 in range(ps.count):\n    p2=ps.item(pj2)\n    ok=False\n    try: ok=(p2.id=='a.YnVzaW5lc3M6YWRvbTMjMjAyMzExMjk3MDM5NjAzMzE')\n    except Exception: ok=False\n    if not ok:\n     try: ok=(p2.name=='Main')\n     except Exception: continue\n    if ok: proj=p2; break\n   if proj: break\n except Exception as e: res['projErr']=str(e)[:60]\nif not proj:\n try:\n  hubs=app.data.dataHubs\n  for hi in range(hubs.count):\n   ps=hubs.item(hi).dataProjects\n   for pj2 in range(ps.count):\n    try:\n     p2=ps.item(pj2); p2.rootFolder\n     proj=p2; break\n    except Exception: continue\n   if proj: break\n  if not proj:\n   for hi in range(hubs.count):\n    try:\n     proj=hubs.item(hi).dataProjects.add('Adom'); break\n    except Exception as e: res['createErr']=str(e)[:60]\n except Exception as e: res['projErr2']=str(e)[:60]\nif not proj: res['errorCode']='no_cloud_project'\ntry:\n if proj is None: raise RuntimeError('no usable cloud project on this account')\n rf=proj.rootFolder\n wsf=_sub(_sub(rf,'Adom AI Workspace'),'AI 3D packages')\n try:\n  doc.saveAs('chip_3d', wsf, '3d package (footprint+chip)', '')\n except Exception as _se:\n  if 'CB_NAE' in str(_se) or 'same name' in str(_se):\n   import time as _t0; _nm='chip_3d-'+_t0.strftime('%m%d%H%M%S')\n   doc.saveAs(_nm, wsf, '3d package (footprint+chip)', ''); res['renamedTo']=_nm\n  else: raise\n import time as _tt\n fid=None\n for w in range(40):\n  try: fid=doc.dataFile.id if doc.dataFile else None\n  except Exception: fid=None\n  if fid and 'dm.lineage:' in str(fid): break\n  adsk.doEvents(); _tt.sleep(1.5)\n res['path']=fid\n res['dims']=[round(dx*10,2),round(dy*10,2),round(dz*10,2)]\nexcept Exception as e: res['err']=str(e)[:80]\nresult=res\n"
  }
]