seveibar/am3352-dev-board-4layer-dogbone

Defines PCB footprints and pin mappings for a TI AM3352ZCZ100 processor, JST GH connectors, and assembly-part lookup helpers for capacitors, resistors, and headers.

Version
0.1.5
License
unset
Stars
0

scripts/patch-pour-connectivity.mjs

/** Include real copper-pour contact in the pinned native connectivity map. */
import fs from 'node:fs'
const marker='physicalPourContactConnections'
const needle='    return new ConnectivityMap(findConnectedNetworks(connections));'
const addition=`    // physicalPourContactConnections: join contacts only within each rendered pour polygon.
    const flattenRing=(vertices)=>{
      const result=[];
      for(let i=0;i<vertices.length;i++){
        const p=vertices[i],q=vertices[(i+1)%vertices.length],b=p.bulge||0;
        result.push(p);
        if(Math.abs(b)<1e-10)continue;
        const dx=q.x-p.x,dy=q.y-p.y,cx=(p.x+q.x)/2-dy*(1-b*b)/(4*b),cy=(p.y+q.y)/2+dx*(1-b*b)/(4*b);
        const a=Math.atan2(p.y-cy,p.x-cx),theta=4*Math.atan(b),r=Math.hypot(p.x-cx,p.y-cy),n=Math.max(2,Math.ceil(Math.abs(theta)/(Math.PI/64)));
        for(let k=1;k<n;k++)result.push({x:cx+r*Math.cos(a+theta*k/n),y:cy+r*Math.sin(a+theta*k/n)});
      }
      return result;
    };
    const inRing=(p,ring)=>{
      let inside=false;
      for(let i=0,j=ring.length-1;i<ring.length;j=i++){
        const a=ring[i],b=ring[j];
        if((a.y>p.y)!==(b.y>p.y)&&p.x<(b.x-a.x)*(p.y-a.y)/(b.y-a.y)+a.x)inside=!inside;
      }
      return inside;
    };
    for(const pour of this.circuitJson.filter(e=>e.type==='pcb_copper_pour')){
      const outer=pour.shape==='brep'?flattenRing(pour.brep_shape.outer_ring.vertices):pour.shape==='polygon'?pour.points:null;
      if(!outer)continue;
      const holes=pour.shape==='brep'?pour.brep_shape.inner_rings.map(r=>flattenRing(r.vertices)):[];
      const contains=p=>inRing(p,outer)&&!holes.some(r=>inRing(p,r));
      const hits=[];
      for(const trace of this.traceIdToElm.values()){
        const direct=trace.route.some(p=>p.route_type==='wire'&&p.layer===pour.layer&&contains(p));
        const viaContact=physicalVias.some(v=>v.pcb_trace_id===trace.pcb_trace_id&&(v.layers||[v.from_layer,v.to_layer]).includes(pour.layer)&&contains(v));
        if(direct||viaContact)hits.push(trace.pcb_trace_id);
      }
      for(const id of hits.slice(1))connections.push([hits[0],id]);
    }
`;
let patched=0;
for(const file of ['node_modules/circuit-json-to-connectivity-map/dist/index.js','node_modules/@tscircuit/cli/dist/cli/main.js','node_modules/@tscircuit/cli/dist/lib/index.js']){
 if(!fs.existsSync(file))continue;
 let s=fs.readFileSync(file,'utf8');if(s.includes(marker))continue;
 const start=s.indexOf('  _buildTraceConnectivityMap() {');const at=s.indexOf(needle,start);
 if(start<0)continue;
 if(at<0||!s.slice(start,at).includes('viaPhysicalContactConnections'))throw Error('Install via contact patch first: '+file);
 fs.writeFileSync(file,s.slice(0,at)+addition+s.slice(at));patched++;
}
console.log('Physical pour contact connectivity installed:',patched,'files patched');