seveibar/f1c1990s-dev-board
This code manages the entire PCB assembly process for a computer hardware module, including component placement, schematic integration, automated routing, copper pouring, and design rule checks, focused on a four-layer carrier board with integrated support components and connectors.
- Version
- 1.8.0
- License
- unset
- Stars
- 0
assembly-metadata.ts
import modelMap from './assembly-models.json'
import partMap from './assembly-parts.json'
/** Restore assembly metadata after the imported module is inflated. This changes
* only source part identifiers and CAD records, never pads, copper, or DRC. */
export function applyPartMetadata(board: any) {
const parts=partMap as Record<string, any>
const walk=(node:any)=>{
const part=parts[node.props?.name]
if(part){Object.assign(node.props,part);Object.assign(node._parsedProps,part)}
for(const child of node.children??[])walk(child)
}
walk(board)
for(const c of board.root.db.source_component.list()) {
const part=parts[c.name]
if(part)board.root.db.source_component.update(c.source_component_id,{
manufacturer_part_number:part.manufacturerPartNumber,
supplier_part_numbers:part.supplierPartNumbers,
})
}
}
export function applyCadMetadata(board:any) {
const db=board.root.db, models=modelMap as Record<string,any>
for(const c of db.source_component.list()) {
// Bare debug holes are copper features and have no fitted 3D body.
if(c.ftype==='simple_test_point') {
const cad=db.cad_component.getWhere({source_component_id:c.source_component_id})
if(cad)db.cad_component.delete(cad.cad_component_id)
continue
}
const specification=models[c.name];if(!specification)continue
const {rotationOffset=0,kind,model_source,...model}=specification
const pcb=db.pcb_component.getWhere({source_component_id:c.source_component_id})
if(!pcb || pcb.do_not_place)continue
const bottom=pcb.layer==='bottom'
const previous=db.cad_component.getWhere({source_component_id:c.source_component_id})
const data={...model,show_as_bounding_box:false,
source_component_id:c.source_component_id,pcb_component_id:pcb.pcb_component_id,
position:{x:pcb.center.x,y:pcb.center.y,z:(bottom?-1:1)*0.7},
rotation:{x:0,y:bottom?180:0,z:bottom?-(pcb.rotation+rotationOffset):pcb.rotation+rotationOffset},
model_origin_alignment:'center_of_component_on_board_surface',
anchor_alignment:'center_of_component_on_board_surface',
}
if(previous)db.cad_component.update(previous.cad_component_id,data)
else db.cad_component.insert(data)
}
}
/** Through-hole headers and bare breakout holes are not paste-in-hole parts.
* The pinned inflator emits paste on both faces of those holes; retain only
* the explicitly associated top-side SMT paste openings. Copper is untouched. */
export function applyAssemblyPasteMetadata(board:any) {
const db=board.root.db
for(const paste of db.pcb_solder_paste.list()) {
const pad=paste.pcb_smtpad_id ? db.pcb_smtpad.get(paste.pcb_smtpad_id) : undefined
if(!pad) { db.pcb_solder_paste.delete(paste.pcb_solder_paste_id); continue }
if(pad.layer!=="top" || paste.layer!=="top")
throw new Error("Single-sided assembly cannot contain bottom SMT paste")
}
}