From ed2a4f61c85967f486f58cdff2f8ea92de50117f Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Wed, 22 Jan 2025 00:22:02 +0100 Subject: [PATCH 1/3] code formatting cleanups --- src/findnet.c | 125 +++++++++++++++++++++++++++++++------------------- src/xschem.h | 6 --- 2 files changed, 77 insertions(+), 54 deletions(-) diff --git a/src/findnet.c b/src/findnet.c index e5373fd8..9ae10407 100644 --- a/src/findnet.c +++ b/src/findnet.c @@ -25,18 +25,18 @@ static double distance; /* safe to keep even with multiple schematics */ static Selected sel; /* safe to keep even with multiple schematics */ -static void find_closest_net(double mx,double my) +static void find_closest_net(double mx, double my) /* returns the net that is closest to the mouse pointer */ /* if there are nets and distance < CADWIREMINDIST */ { double tmp; - int i,w=-1; + int i, w=-1; double threshold; threshold = CADWIREMINDIST * CADWIREMINDIST * xctx->zoom * xctx->zoom; for(i=0;iwires; ++i) { - if( (tmp = dist(xctx->wire[i].x1,xctx->wire[i].y1,xctx->wire[i].x2,xctx->wire[i].y2,mx,my)) < distance ) + if( (tmp = dist(xctx->wire[i].x1, xctx->wire[i].y1, xctx->wire[i].x2, xctx->wire[i].y2, mx, my)) < distance ) { w = i; distance = tmp; } @@ -104,7 +104,7 @@ static void find_closest_bezier(double mx, double my, int c, int i, int *l, int } } -static void find_closest_polygon(double mx,double my) +static void find_closest_polygon(double mx, double my) /* returns the polygon that is closest to the mouse pointer */ /* if there are lines and distance < CADWIREMINDIST */ { @@ -138,7 +138,7 @@ static void find_closest_polygon(double mx,double my) y1 = p->y[j]; x2 = p->x[j+1]; y2 = p->y[j+1]; - ORDER(x1,y1,x2,y2); + ORDER(x1, y1, x2, y2); if( (tmp = dist(x1, y1, x2, y2, mx, my)) < distance ) { l = i; distance = tmp;col = c; @@ -155,12 +155,12 @@ static void find_closest_polygon(double mx,double my) } -static void find_closest_line(double mx,double my) +static void find_closest_line(double mx, double my) /* returns the line that is closest to the mouse pointer */ /* if there are lines and distance < CADWIREMINDIST */ { double tmp; - int i,c,l=-1, col = 0; + int i, c, l = -1, col = 0; double threshold; threshold = CADWIREMINDIST * CADWIREMINDIST * xctx->zoom * xctx->zoom; for(c=0;cenable_layer[c]) continue; for(i=0;ilines[c]; ++i) { - if( (tmp = dist(xctx->line[c][i].x1,xctx->line[c][i].y1,xctx->line[c][i].x2,xctx->line[c][i].y2,mx,my)) + if( (tmp = dist(xctx->line[c][i].x1, xctx->line[c][i].y1, xctx->line[c][i].x2, xctx->line[c][i].y2, mx, my)) < distance ) { l = i; distance = tmp;col = c; @@ -182,31 +182,60 @@ static void find_closest_line(double mx,double my) } } + +/* sample code: find all inst and wire endpoints around (mx, my) */ +#if 0 +static void xfind_closest_net_or_symbol_pin(double mx, double my, double *x, double *y) +{ + int sqx, sqy; + Instpinentry *iptr; + Wireentry *wptr; + double xx, yy; + + get_square(mx, my, &sqx, &sqy); + for(iptr = xctx->instpin_spatial_table[sqx][sqy]; iptr; iptr = iptr->next) { + int n = iptr->n; + if( !((xctx->inst[n].ptr + xctx->sym)->type) ) continue; + xx = iptr->x0; + yy = iptr->y0; + } + for(wptr = xctx->wire_spatial_table[sqx][sqy]; wptr; wptr = wptr->next) { + int n = wptr->n; + xWire *w = &xctx->wire[n]; + xx = w->x1; + yy = w->y1; + + xx = w->x2; + yy = w->y2; + } +} +#endif + /* 20171022 snap wire to closest pin or net endpoint */ -void find_closest_net_or_symbol_pin(double mx,double my, double *x, double *y) +void find_closest_net_or_symbol_pin(double mx, double my, double *x, double *y) { int i, j, no_of_pin_rects; - double x0, x1, x2, y0, y1, y2, xx, yy, dist, min_dist_x=0, min_dist_y=0; + double x0, x1, x2, y0, y1, y2, xx, yy, dist, min_dist_x = 0, min_dist_y = 0; xRect rect; short rot, flip; - char *type=NULL; + char *type = NULL; double curr_dist; curr_dist = DBL_MAX; - for(i=0;iinstances; ++i) { + for(i = 0;i < xctx->instances; ++i) { x0=xctx->inst[i].x0; y0=xctx->inst[i].y0; rot = xctx->inst[i].rot; flip = xctx->inst[i].flip; - my_strdup(_ALLOC_ID_, &type,(xctx->inst[i].ptr+ xctx->sym)->type); + my_strdup(_ALLOC_ID_, &type, (xctx->inst[i].ptr+ xctx->sym)->type); if(!type) continue; no_of_pin_rects = (xctx->inst[i].ptr+ xctx->sym)->rects[PINLAYER]; if(IS_LABEL_OR_PIN(type)) no_of_pin_rects=1; for(j=0; jinst[i].ptr+ xctx->sym)->rect[PINLAYER])[j]; - ROTATION(rot, flip, 0.0,0.0,rect.x1,rect.y1,x1,y1); - ROTATION(rot, flip, 0.0,0.0,rect.x2,rect.y2,x2,y2); + ROTATION(rot, flip, 0.0, 0.0, rect.x1, rect.y1, x1, y1); + ROTATION(rot, flip, 0.0, 0.0, rect.x2, rect.y2, x2, y2); x1 += x0; y1 += y0; x2 += x0; @@ -221,8 +250,8 @@ void find_closest_net_or_symbol_pin(double mx,double my, double *x, double *y) } } } - for(i=0;iwires; ++i) { - xx=xctx->wire[i].x1; + for(i = 0;i < xctx->wires; ++i) { + xx = xctx->wire[i].x1; yy = xctx->wire[i].y1; dist = (mx - xx) * (mx - xx) + (my - yy) * (my - yy); if(dist < curr_dist) { @@ -230,7 +259,7 @@ void find_closest_net_or_symbol_pin(double mx,double my, double *x, double *y) min_dist_x = xx; min_dist_y = yy; } - xx=xctx->wire[i].x2; + xx = xctx->wire[i].x2; yy = xctx->wire[i].y2; dist = (mx - xx) * (mx - xx) + (my - yy) * (my - yy); if(dist < curr_dist) { @@ -244,10 +273,10 @@ void find_closest_net_or_symbol_pin(double mx,double my, double *x, double *y) my_free(_ALLOC_ID_, &type); } -static void find_closest_arc(double mx,double my) +static void find_closest_arc(double mx, double my) { double dist, angle, angle1, angle2; - int i,c,r=-1, col; + int i, c, r=-1, col; int match; double threshold; threshold = CADWIREMINDIST * CADWIREMINDIST * xctx->zoom * xctx->zoom; @@ -257,7 +286,7 @@ static void find_closest_arc(double mx,double my) if(!xctx->enable_layer[c]) continue; for(i=0;iarcs[c]; ++i) { - dist = sqrt(pow(mx-xctx->arc[c][i].x,2) + pow(my-xctx->arc[c][i].y,2)) - xctx->arc[c][i].r; + dist = sqrt(pow(mx-xctx->arc[c][i].x, 2) + pow(my-xctx->arc[c][i].y, 2)) - xctx->arc[c][i].r; dist *= dist; /* square distance */ angle = fmod(atan2(xctx->arc[c][i].y-my, mx-xctx->arc[c][i].x)*180./XSCH_PI, 360.); if(angle<0.) angle +=360.; @@ -278,7 +307,7 @@ static void find_closest_arc(double mx,double my) } } dbg(1, "find_closest_arc(): dist = %g, angle = %g\n", dist, angle); - dbg(1, "find_closest_arc(): center=%g,%g: mouse: %g:%g\n", + dbg(1, "find_closest_arc(): center=%g, %g: mouse: %g:%g\n", xctx->arc[c][i].x, xctx->arc[c][i].y, mx, my); if(match ) { dbg(1, "find_closest_arc(): i = %d\n", i); @@ -288,29 +317,29 @@ static void find_closest_arc(double mx,double my) } } /* end for i */ } /* end for c */ - if( r!=-1 && distance <= threshold ) /* * pow(xctx->arc[col][r].r,2)) */ + if( r!=-1 && distance <= threshold ) /* * pow(xctx->arc[col][r].r, 2)) */ { sel.n = r; sel.type = ARC; sel.col = col; } } -static void find_closest_box(double mx,double my, int override_lock) +static void find_closest_box(double mx ,double my, int override_lock) { double tmp; double ds = xctx->cadhalfdotsize; - int i,c,r=-1, col = 0; + int i, c, r=-1, col = 0; for(c=0;cenable_layer[c]) continue; for(i=0;irects[c]; ++i) { - if( POINTINSIDE(mx,my,xctx->rect[c][i].x1 - ds, xctx->rect[c][i].y1 - ds, + if( POINTINSIDE(mx, my, xctx->rect[c][i].x1 - ds, xctx->rect[c][i].y1 - ds, xctx->rect[c][i].x2 + ds, xctx->rect[c][i].y2 + ds) ) { - tmp=dist_from_rect(mx,my,xctx->rect[c][i].x1,xctx->rect[c][i].y1, - xctx->rect[c][i].x2,xctx->rect[c][i].y2); + tmp=dist_from_rect(mx, my, xctx->rect[c][i].x1, xctx->rect[c][i].y1, + xctx->rect[c][i].x2, xctx->rect[c][i].y2); if(tmp < distance) { r = i; distance = tmp;col = c; @@ -324,22 +353,22 @@ static void find_closest_box(double mx,double my, int override_lock) } } -static void find_closest_element(double mx,double my, int override_lock) +static void find_closest_element(double mx, double my, int override_lock) { double tmp; - int i,r=-1; + int i, r=-1; for(i=0;iinstances; ++i) { dbg(2, "find_closest_element(): %s: %g %g %g %g\n", - xctx->inst[i].instname, xctx->inst[i].x1,xctx->inst[i].y1,xctx->inst[i].x2,xctx->inst[i].y2); - if( POINTINSIDE(mx,my,xctx->inst[i].x1,xctx->inst[i].y1,xctx->inst[i].x2,xctx->inst[i].y2) ) + xctx->inst[i].instname, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2); + if( POINTINSIDE(mx, my, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2) ) { tmp=pow(mx-(xctx->inst[i].xx1 + xctx->inst[i].xx2)/2, 2)+pow(my-(xctx->inst[i].yy1 + xctx->inst[i].yy2)/2, 2); if(tmp*0.1 < distance) { r = i; distance = tmp*0.1; } - dbg(2, "find_closest_element(): finding closest element, instances=%d, dist=%.16g\n",i,tmp); + dbg(2, "find_closest_element(): finding closest element, instances=%d, dist=%.16g\n", i, tmp); } } /* end for i */ if( r!=-1 && (override_lock || strboolcmp(get_tok_value(xctx->inst[r].prop_ptr, "lock", 0), "true")) ) { @@ -347,11 +376,11 @@ static void find_closest_element(double mx,double my, int override_lock) } } -static void find_closest_text(double mx,double my) +static void find_closest_text(double mx, double my) { - short rot,flip; - double xx1,xx2,yy1,yy2; - int i,r=-1, tmp; + short rot, flip; + double xx1, xx2, yy1, yy2; + int i, r=-1, tmp; double threshold, dtmp; #if HAS_CAIRO==1 int customfont; @@ -370,17 +399,17 @@ static void find_closest_text(double mx,double my) xctx->text[i].xscale, xctx->text[i].yscale, rot, flip, xctx->text[i].hcenter, xctx->text[i].vcenter, xctx->text[i].x0, xctx->text[i].y0, - &xx1,&yy1, &xx2,&yy2, &tmp, &dtmp); + &xx1, &yy1, &xx2, &yy2, &tmp, &dtmp); my_free(_ALLOC_ID_, &estr); #if HAS_CAIRO==1 if(customfont) { cairo_restore(xctx->cairo_ctx); } #endif - if(POINTINSIDE(mx,my,xx1,yy1, xx2, yy2)) + if(POINTINSIDE(mx, my, xx1, yy1, xx2, yy2)) { r = i; distance = 0; - dbg(2, "find_closest_text(): finding closest text, texts=%d, dist=%.16g\n",i,distance); + dbg(2, "find_closest_text(): finding closest text, texts=%d, dist=%.16g\n", i, distance); } } /* end for i */ if( distance <= threshold && r!=-1) @@ -389,19 +418,19 @@ static void find_closest_text(double mx,double my) } } -Selected find_closest_obj(double mx,double my, int override_lock) +Selected find_closest_obj(double mx, double my, int override_lock) { sel.n = 0L; sel.col = 0; sel.type = 0; distance = DBL_MAX; - find_closest_line(mx,my); - find_closest_polygon(mx,my); + find_closest_line(mx, my); + find_closest_polygon(mx, my); /* dbg(1, "1 find_closest_obj(): sel.n=%d, sel.col=%d, sel.type=%d\n", sel.n, sel.col, sel.type); */ - find_closest_box(mx,my, override_lock); - find_closest_arc(mx,my); + find_closest_box(mx, my, override_lock); + find_closest_arc(mx, my); /* dbg(1, "2 find_closest_obj(): sel.n=%d, sel.col=%d, sel.type=%d\n", sel.n, sel.col, sel.type); */ - find_closest_text(mx,my); - find_closest_net(mx,my); - find_closest_element(mx,my, override_lock); + find_closest_text(mx, my); + find_closest_net(mx, my); + find_closest_element(mx, my, override_lock); return sel; /*sel.type = 0 if nothing found */ } diff --git a/src/xschem.h b/src/xschem.h index 67dfc35d..0fcae282 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -773,9 +773,6 @@ struct hilight_hashentry int time; /*delta-time for sims */ }; - - - typedef struct { /* spice raw file specific data */ char **names; @@ -801,9 +798,6 @@ typedef struct { double sweep1, sweep2; } Raw; - - - /* for netlist.c */ typedef struct instpinentry Instpinentry; struct instpinentry From 0c8631a1012a9da177c6e1448d6c95bfaa4bb175 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Wed, 22 Jan 2025 01:57:09 +0100 Subject: [PATCH 2/3] MotionNotify events with Shift key down (and draw_crosshair enabled) will position the crosshair to the closest available landing point (inst pin or wire endpoint) --- src/callback.c | 18 +++++++++++++++--- src/xschem.tcl | 4 ++-- src/xschemrc | 4 ++-- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/callback.c b/src/callback.c index 07ea4a3e..e776c28b 100644 --- a/src/callback.c +++ b/src/callback.c @@ -1340,7 +1340,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int void draw_crosshair(int what) { int sdw, sdp; - int xhair_size = tclgetintvar("crosshair_size");; + int xhair_size = tclgetintvar("crosshair_size"); dbg(1, "draw_crosshair(): what=%d\n", what); sdw = xctx->draw_window; sdp = xctx->draw_pixmap; @@ -2532,7 +2532,7 @@ int rstate; /* (reduced state, without ShiftMask) */ } } /* Select by area. Shift pressed */ - else if((state&Button1Mask) && (state & ShiftMask) && + else if((state&Button1Mask) && (state & ShiftMask) && !(xctx->ui_state & STARTWIRE) && !(xctx->ui_state & (PLACE_SYMBOL | PLACE_TEXT)) && !xctx->shape_point_selected && !xctx->drag_elements && !(xctx->ui_state & STARTPAN) ) { if(mx != xctx->mx_save || my != xctx->my_save) { @@ -2550,7 +2550,19 @@ int rstate; /* (reduced state, without ShiftMask) */ } } if(draw_xhair) { - draw_crosshair(2); + if(/* (xctx->ui_state & STARTWIRE) && */ (state & ShiftMask) ) { + double x, y, sx, sy; + sx = xctx->mousex_snap; + sy = xctx->mousey_snap; + find_closest_net_or_symbol_pin(xctx->mousex, xctx->mousey, &x, &y); + xctx->mousex_snap = x; + xctx->mousey_snap = y; + draw_crosshair(2); + xctx->mousex_snap = sx; + xctx->mousey_snap = sy; + } else { + draw_crosshair(2); + } } break; diff --git a/src/xschem.tcl b/src/xschem.tcl index a7a88a5a..d0c70af9 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -9095,7 +9095,8 @@ set_ne flat_netlist 0 set_ne netlist_show 0 set_ne color_ps 1 set_ne ps_page_title 1 ;# add a title in the top left page corner -set_ne crosshair_layer 3 ;# TEXTLAYER +set_ne draw_crosshair 0 +set_ne crosshair_layer 8 ;# Yellow set_ne crosshair_size 0 set_ne ps_paper_size {a4 842 595} set_ne transparent_svg 0 @@ -9120,7 +9121,6 @@ set_ne load_file_dialog_fullpath 1 set_ne incremental_select 1 set_ne select_touch 1 -set_ne draw_crosshair 0 set_ne draw_grid 1 set_ne big_grid_points 0 set_ne draw_grid_axes 1 diff --git a/src/xschemrc b/src/xschemrc index f32941cf..70513e40 100644 --- a/src/xschemrc +++ b/src/xschemrc @@ -267,8 +267,8 @@ #### enable drawing crosshairs at mouse coordinates. Default: disabled (0) # set draw_crosshair 1 -#### set crosshair layer; Default 3 (TEXTLAYER) -# set crosshair_layer 3 +#### set crosshair layer; Default 8 (Yellow) +# set crosshair_layer 8 #### set crosshair size; Default: 0 (full screen spanning crosshair) # set crosshair_size 5 From 4e821586c2dce0c83f1e7f4a4b728b48a52f29e5 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Wed, 22 Jan 2025 03:59:49 +0100 Subject: [PATCH 3/3] replaced find_closest_net_or_symbol_pin() with new function that uses spatial hash table iterators for searching --- src/findnet.c | 100 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 71 insertions(+), 29 deletions(-) diff --git a/src/findnet.c b/src/findnet.c index 9ae10407..852e72bb 100644 --- a/src/findnet.c +++ b/src/findnet.c @@ -183,36 +183,77 @@ static void find_closest_line(double mx, double my) } -/* sample code: find all inst and wire endpoints around (mx, my) */ -#if 0 -static void xfind_closest_net_or_symbol_pin(double mx, double my, double *x, double *y) -{ - int sqx, sqy; - Instpinentry *iptr; - Wireentry *wptr; - double xx, yy; - - get_square(mx, my, &sqx, &sqy); - for(iptr = xctx->instpin_spatial_table[sqx][sqy]; iptr; iptr = iptr->next) { - int n = iptr->n; - if( !((xctx->inst[n].ptr + xctx->sym)->type) ) continue; - xx = iptr->x0; - yy = iptr->y0; - } - for(wptr = xctx->wire_spatial_table[sqx][sqy]; wptr; wptr = wptr->next) { - int n = wptr->n; - xWire *w = &xctx->wire[n]; - xx = w->x1; - yy = w->y1; - - xx = w->x2; - yy = w->y2; - } -} -#endif - -/* 20171022 snap wire to closest pin or net endpoint */ +/* snap wire to closest pin or net endpoint (if it is inside the current screen viewport) */ +/* use spatial hash table iterators to avoid O(N) */ void find_closest_net_or_symbol_pin(double mx, double my, double *x, double *y) +{ + double x1, y1, x2, y2; + Iterator_ctx ctx; + Instentry *instanceptr; + Wireentry *wireptr; + double curr_dist = DBL_MAX; + double xx, yy, dist, min_dist_x = xctx->mousex_snap, min_dist_y = xctx->mousey_snap; + + x1 = X_TO_XSCHEM(xctx->areax1); + y1 = Y_TO_XSCHEM(xctx->areay1); + x2 = X_TO_XSCHEM(xctx->areax2); + y2 = Y_TO_XSCHEM(xctx->areay2); + + hash_instances(); + hash_wires(); + + init_inst_iterator(&ctx, x1, y1, x2, y2); + while(1) { + int i, j, rects; + xInstance * const inst = xctx->inst; + if( !(instanceptr = inst_iterator_next(&ctx))) break; + i = instanceptr->n; + if(!((inst[i].ptr+ xctx->sym)->type)) continue; + rects = (inst[i].ptr+ xctx->sym)->rects[PINLAYER]; + for(j = 0; j < rects; j++) { + get_inst_pin_coord(i, j, &xx, &yy); + if(!POINTINSIDE(xx, yy, x1, y1, x2, y2)) continue; + dist = (mx - xx) * (mx - xx) + (my - yy) * (my - yy); + if(dist < curr_dist) { + curr_dist = dist; + min_dist_x = xx; + min_dist_y = yy; + } + } + } + + init_wire_iterator(&ctx, x1, y1, x2, y2); + while(1) { + int i; + xWire * const wire = xctx->wire; + if( !(wireptr = wire_iterator_next(&ctx))) break; + i = wireptr->n; + xx = wire[i].x1; + yy = wire[i].y1; + if(!POINTINSIDE(xx, yy, x1, y1, x2, y2)) continue; + dist = (mx - xx) * (mx - xx) + (my - yy) * (my - yy); + if(dist < curr_dist) { + curr_dist = dist; + min_dist_x = xx; + min_dist_y = yy; + } + xx = wire[i].x2; + yy = wire[i].y2; + if(!POINTINSIDE(xx, yy, x1, y1, x2, y2)) continue; + dist = (mx - xx) * (mx - xx) + (my - yy) * (my - yy); + if(dist < curr_dist) { + curr_dist = dist; + min_dist_x = xx; + min_dist_y = yy; + } + } + + *x = min_dist_x; + *y = min_dist_y; +} + +#if 0 +void xfind_closest_net_or_symbol_pin(double mx, double my, double *x, double *y) { int i, j, no_of_pin_rects; double x0, x1, x2, y0, y1, y2, xx, yy, dist, min_dist_x = 0, min_dist_y = 0; @@ -272,6 +313,7 @@ void find_closest_net_or_symbol_pin(double mx, double my, double *x, double *y) *y = min_dist_y; my_free(_ALLOC_ID_, &type); } +#endif static void find_closest_arc(double mx, double my) {