@@ -13,15 +13,20 @@ interface SilkscreenElementWithBounds {
1313 * Adjust silkscreen reference designators for passive components to avoid overlaps
1414 * This phase runs after PCB layout is complete but before final rendering
1515 *
16- * PERFORMANCE OPTIMIZATIONS :
17- * 1. Direct silkscreen element access: Uses rootCircuit .selectAll("silkscreen* ") to get all elements directly
18- * 2. Spatial filtering: Only processes silkscreen elements within search radius
19- * 3. Component-aware database access: Direct .get(id) calls for fresh state
16+ * APPROACH :
17+ * 1. Uses component .selectAll("silkscreentext ") to discover silkscreen text components
18+ * 2. Links components to database records for position data and update operations
19+ * 3. Performs overlap detection and position adjustment as needed
2020 *
21- * Performance improvement: From O(N*M*K) to O(S) where:
22- * - S = number of silkscreen component instances (much smaller than total DB records)
23- * - No component discovery overhead - get silkscreen elements directly
24- * - No complex component hierarchy traversal needed
21+ * PERFORMANCE BENEFITS:
22+ * - Uses selectAll() for component discovery (avoids database traversal)
23+ * - Targeted database queries only for components that exist
24+ * - Minimal database access compared to full table scanning approaches
25+ *
26+ * Note: Some database access is still required because:
27+ * - Database records contain the authoritative position data
28+ * - Position updates must be written back to the database
29+ * - Component-DB linking timing issues require fallback record matching
2530 */
2631export function NormalComponent_doInitialSilkscreenOverlapAdjustment (
2732 component : NormalComponent < any > ,
@@ -32,35 +37,62 @@ export function NormalComponent_doInitialSilkscreenOverlapAdjustment(
3237 // Only adjust silkscreen text for components that opt in
3338 if ( ! component . _adjustSilkscreenTextAutomatically ) return
3439
35- // Get this component's silkscreen texts (minimal DB query)
36- const componentSilkscreenTexts = component . pcb_component_id
37- ? db . pcb_silkscreen_text
38- . list ( )
39- . filter ( ( text ) => text . pcb_component_id === component . pcb_component_id )
40- : [ ]
40+ // Use selectAll to find silkscreen text components (avoids database traversal)
41+ const silkscreenTextComponents = component . selectAll ( "silkscreentext" )
4142
42- if ( componentSilkscreenTexts . length === 0 ) return
43+ if ( silkscreenTextComponents . length === 0 ) return
4344
4445 // Get component center early to avoid repeated lookups
4546 const componentCenter = getComponentCenterFromCache ( component , db )
4647 if ( ! componentCenter ) return
4748
48- // Get all silkscreen elements from database (using selectAll for component discovery)
49- const nearbySilkscreenElements = getAllSilkscreenElementsFromDB (
50- component . root ,
51- db ,
52- )
49+ // For each silkscreen text component found, get its database record for processing
50+ for ( const textComponent of silkscreenTextComponents ) {
51+ // Skip if this component doesn't have the required data
52+ if ( ! textComponent . props ?. text ) continue
53+
54+ // Get the database record for this specific text component
55+ // Note: We need the DB record for accurate position data and update operations
56+ let textDbRecord : any = null
57+
58+ // Try direct ID lookup first (most efficient)
59+ if ( ( textComponent as any ) . pcb_silkscreen_text_id ) {
60+ textDbRecord = db . pcb_silkscreen_text . get (
61+ ( textComponent as any ) . pcb_silkscreen_text_id ,
62+ )
63+ }
64+
65+ // If direct lookup fails, we need to find the matching database record
66+ // This is necessary because the component-DB linking might not be complete yet
67+ if ( ! textDbRecord && component . pcb_component_id ) {
68+ // Use a targeted database query (filter by component ID, not full table scan)
69+ const candidateTexts = db . pcb_silkscreen_text
70+ . list ( )
71+ . filter ( ( t ) => t . pcb_component_id === component . pcb_component_id )
72+
73+ // Match by text content to find the right record
74+ textDbRecord = candidateTexts . find (
75+ ( t ) => t . text === textComponent . props . text ,
76+ )
77+ }
78+
79+ if ( ! textDbRecord ) continue
80+
81+ const textBounds = getSilkscreenTextBounds ( textDbRecord )
82+
83+ // Get all silkscreen elements from database (using selectAll for component discovery)
84+ const nearbySilkscreenElements = getAllSilkscreenElementsFromDB (
85+ component . root ,
86+ db ,
87+ )
5388
54- // For each silkscreen text, check for overlaps and adjust if needed
55- for ( const refText of componentSilkscreenTexts ) {
56- const textBounds = getSilkscreenTextBounds ( refText )
5789 let hasOverlap = false
5890
5991 // Check overlap with nearby silkscreen elements only (much faster than checking all)
6092 for ( const element of nearbySilkscreenElements ) {
6193 if (
62- element . layer === refText . layer &&
63- element . element_id !== refText . pcb_silkscreen_text_id
94+ element . layer === textDbRecord . layer &&
95+ element . element_id !== textDbRecord . pcb_silkscreen_text_id
6496 ) {
6597 if ( boundsOverlap ( textBounds , element . bounds ) ) {
6698 hasOverlap = true
@@ -72,8 +104,8 @@ export function NormalComponent_doInitialSilkscreenOverlapAdjustment(
72104 if ( hasOverlap ) {
73105 // Try flipping to the opposite side
74106 const currentOffset = {
75- x : refText . anchor_position . x - componentCenter . x ,
76- y : refText . anchor_position . y - componentCenter . y ,
107+ x : textDbRecord . anchor_position . x - componentCenter . x ,
108+ y : textDbRecord . anchor_position . y - componentCenter . y ,
77109 }
78110
79111 const flippedPosition = {
@@ -96,8 +128,8 @@ export function NormalComponent_doInitialSilkscreenOverlapAdjustment(
96128 // Check the flipped position against nearby elements only
97129 for ( const element of nearbySilkscreenElements ) {
98130 if (
99- element . layer === refText . layer &&
100- element . element_id !== refText . pcb_silkscreen_text_id
131+ element . layer === textDbRecord . layer &&
132+ element . element_id !== textDbRecord . pcb_silkscreen_text_id
101133 ) {
102134 if ( boundsOverlap ( flippedTextBounds , element . bounds ) ) {
103135 flippedHasOverlap = true
@@ -108,7 +140,7 @@ export function NormalComponent_doInitialSilkscreenOverlapAdjustment(
108140
109141 if ( ! flippedHasOverlap ) {
110142 // Update to the flipped position
111- db . pcb_silkscreen_text . update ( refText . pcb_silkscreen_text_id , {
143+ db . pcb_silkscreen_text . update ( textDbRecord . pcb_silkscreen_text_id , {
112144 anchor_position : flippedPosition ,
113145 } )
114146 }
0 commit comments