Index: trunk/scconfig/Rev.h =================================================================== --- trunk/scconfig/Rev.h (revision 38724) +++ trunk/scconfig/Rev.h (revision 38725) @@ -1 +1 @@ -static const int myrev = 38523; +static const int myrev = 38724; Index: trunk/scconfig/Rev.tab =================================================================== --- trunk/scconfig/Rev.tab (revision 38724) +++ trunk/scconfig/Rev.tab (revision 38725) @@ -1,3 +1,4 @@ +38724 configure new experimental plugin: rubber band stretch router 38523 configure require librnd >=4.1.0 and enable font2 38351 configure font mode: preview dialog 38025 configure export_bom2: new bom plugin with templates Index: trunk/scconfig/plugins.h =================================================================== --- trunk/scconfig/plugins.h (revision 38724) +++ trunk/scconfig/plugins.h (revision 38725) @@ -47,6 +47,7 @@ plugin_def("propedit", "object property editor", sbuildin, 1) plugin_def("puller", "puller", sbuildin, 1) plugin_def("query", "query language", sbuildin, 1) +plugin_def("rbs_routing", "Rubber Band Stretch Routing", sdisable, 0) plugin_def("renumber", "renumber action", sbuildin, 1) plugin_def("report", "report actions", sbuildin, 1) plugin_def("rubberband_orig", "the original rubberband", sbuildin, 1) Index: trunk/src/Makefile.dep =================================================================== --- trunk/src/Makefile.dep (revision 38724) +++ trunk/src/Makefile.dep (revision 38725) @@ -2359,6 +2359,16 @@ obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h ../config.h \ obj_text_list.h obj_text.h font.h obj_gfx_list.h obj_gfx.h flag_str.h \ ../src_plugins/query/query_l.h +../src_plugins/rbs_routing/rbs_routing.o: \ + ../src_plugins/rbs_routing/rbs_routing.c ../config.h board.h \ + vtroutestyle.h attrib.h global_typedefs.h layer.h globalconst.h \ + obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ + obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h obj_text_list.h \ + obj_text.h font.h obj_gfx_list.h obj_gfx.h layer_grp.h rats_patch.h \ + board.h data.h crosshair.h route.h buffer.h obj_rat_list.h obj_rat.h \ + idpath.h obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h \ + ht_subc.h obj_pstk_list.h obj_pstk.h vtpadstack.h obj_pstk_shape.h \ + polygon.h vtpadstack_t.h ../src_plugins/rbs_routing/menu_internal.c ../src_plugins/renumber/renumber.o: ../src_plugins/renumber/renumber.c \ ../config.h board.h vtroutestyle.h attrib.h global_typedefs.h layer.h \ globalconst.h obj_common.h flag.h data_parent.h obj_arc_list.h obj_arc.h \ Index: trunk/src_plugins/plugins_ALL.tmpasm =================================================================== --- trunk/src_plugins/plugins_ALL.tmpasm (revision 38724) +++ trunk/src_plugins/plugins_ALL.tmpasm (revision 38725) @@ -99,6 +99,7 @@ include {../src_plugins/propedit/Plug.tmpasm} include {../src_plugins/puller/Plug.tmpasm} include {../src_plugins/query/Plug.tmpasm} +include {../src_plugins/rbs_routing/Plug.tmpasm} include {../src_plugins/renumber/Plug.tmpasm} include {../src_plugins/report/Plug.tmpasm} include {../src_plugins/rubberband_orig/Plug.tmpasm} Index: trunk/src_plugins/rbs_routing/Makefile =================================================================== --- trunk/src_plugins/rbs_routing/Makefile (nonexistent) +++ trunk/src_plugins/rbs_routing/Makefile (revision 38725) @@ -0,0 +1,6 @@ +all: + cd ../../src && $(MAKE) mod_rbs_routing + +clean: + rm *.o *.so 2>/dev/null ; true + Index: trunk/src_plugins/rbs_routing/Plug.tmpasm =================================================================== --- trunk/src_plugins/rbs_routing/Plug.tmpasm (nonexistent) +++ trunk/src_plugins/rbs_routing/Plug.tmpasm (revision 38725) @@ -0,0 +1,13 @@ +put /local/rnd/mod {rbs_routing} +put /local/rnd/mod/MENUFILE {rbs_routing-menu.lht} +put /local/rnd/mod/MENUVAR {rbs_routing_menu} +append /local/rnd/mod/OBJS [@ + $(PLUGDIR)/rbs_routing/rbs_routing.o +@] + +switch /local/module/rbs_routing/controls + case {buildin} include /local/pcb/tmpasm/buildin; end; + case {plugin} include /local/pcb/tmpasm/plugin; end; + case {disable} include /local/pcb/tmpasm/disable; end; +end + Index: trunk/src_plugins/rbs_routing/rbs_routing-menu.lht =================================================================== --- trunk/src_plugins/rbs_routing/rbs_routing-menu.lht (nonexistent) +++ trunk/src_plugins/rbs_routing/rbs_routing-menu.lht (revision 38725) @@ -0,0 +1,15 @@ +ha:rnd-menu-v1 { + li:main_menu { + ha:Connects = { + li:submenu { + ha:Rubber Band Stretch Routing { + li:submenu { + ha:Connect = { a={r;s;c;}; action=RbsConnect() } + ha:Stretch = { a={r;s;s;}; action=RbsStretch() } + } + } + } + } + } + } +} Index: trunk/src_plugins/rbs_routing/rbs_routing.c =================================================================== --- trunk/src_plugins/rbs_routing/rbs_routing.c (nonexistent) +++ trunk/src_plugins/rbs_routing/rbs_routing.c (revision 38725) @@ -0,0 +1,73 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2024 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include "board.h" +#include "data.h" + +#include +#include +#include +#include "menu_internal.c" + +static const char pcb_acts_RbsConnect[] = "RbsConnect()"; +static const char pcb_acth_RbsConnect[] = "Make a new rubber band stretch connection between two points"; +/* DOC: ... */ +static fgw_error_t pcb_act_RbsConnect(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ +} + +static const char pcb_acts_RbsStretch[] = "RbsStretch()"; +static const char pcb_acth_RbsStretch[] = "Make a new rubber band stretch connection between two points"; +/* DOC: ... */ +static fgw_error_t pcb_act_RbsStretch(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ +} + +rnd_action_t rbs_routing_action_list[] = { + {"RbsConnect", pcb_act_RbsConnect, pcb_acth_RbsConnect, pcb_acts_RbsConnect}, + {"RbsStretch", pcb_act_RbsStretch, pcb_acth_RbsStretch, pcb_acts_RbsStretch} +}; + + +static const char *rbs_routing_cookie = "rbs_routing plugin"; + +int pplg_check_ver_rbs_routing(int ver_needed) { return 0; } + +void pplg_uninit_rbs_routing(void) +{ + rnd_remove_actions_by_cookie(rbs_routing_cookie); + rnd_hid_menu_unload(rnd_gui, rbs_routing_cookie); +} + +int pplg_init_rbs_routing(void) +{ + RND_API_CHK_VER; + RND_REGISTER_ACTIONS(rbs_routing_action_list, rbs_routing_cookie) + rnd_hid_menu_load(rnd_gui, NULL, rbs_routing_cookie, 175, NULL, 0, rbs_routing_menu, "plugin: rbs_routing"); + return 0; +} Index: trunk/src_plugins/rbs_routing/rbs_routing.pup =================================================================== --- trunk/src_plugins/rbs_routing/rbs_routing.pup (nonexistent) +++ trunk/src_plugins/rbs_routing/rbs_routing.pup (revision 38725) @@ -0,0 +1,7 @@ +$class feature +$short Rubber Band Stretch Routing +$long Assisted routing by stretching traces as if they were rubber bands +$state WIP +$package core +default disable-all +autoload 1 Index: trunk/src_plugins/rbs_routing/show_netnames.c =================================================================== --- trunk/src_plugins/rbs_routing/show_netnames.c (nonexistent) +++ trunk/src_plugins/rbs_routing/show_netnames.c (revision 38725) @@ -0,0 +1,309 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2020 Tibor 'Igor2' Palinkas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact: + * Project page: http://repo.hu/projects/pcb-rnd + * lead developer: http://repo.hu/projects/pcb-rnd/contact.html + * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "board.h" +#include "conf_core.h" +#include "draw.h" +#include "event.h" +#include "netlist.h" +#include "select.h" +#include "obj_text_draw.h" +#include "../src_plugins/query/net_int.h" + +#include "show_netnames_conf.h" +#include "menu_internal.c" +#include "conf_internal.c" + +const char *pcb_show_netnames_cookie = "show_netnames plugin"; +conf_show_netnames_t conf_show_netnames; + +static pcb_qry_exec_t shn_qctx; + +typedef struct { + rnd_coord_t w, h; /* bbox width and height when netname drawn with 100% font scale */ + unsigned show:1; /* 1 if label should be printed */ +} shn_net_t; + +static shn_net_t shn_invalid = {0}; + +#define HT_HAS_CONST_KEY +#define HT_INVALID_VALUE shn_invalid +typedef void *htshn_key_t; +typedef const void *htshn_const_key_t; +typedef shn_net_t htshn_value_t; +#define HT(x) htshn_ ## x +#include +#include +#undef HT +#undef HT_INVALID_VALIUE + + +static htshn_t shn_cache; +static int shn_cache_inited; +static int shn_cache_uptodate; +static shn_net_t shn_nonet; + +static void shn_cache_update(pcb_board_t *pcb) +{ + pcb_net_t *net; + pcb_net_it_t it; + pcb_text_t t = {0}; + rnd_conf_listitem_t *ci; + vtp0_t omit_netnames = {0}; + int n; + + if (shn_cache_inited) + htshn_clear(&shn_cache); + else + htshn_init(&shn_cache, ptrhash, ptrkeyeq); + + for(ci = rnd_conflist_first((rnd_conflist_t *)&conf_show_netnames.plugins.show_netnames.omit_netnames); ci != NULL; ci = rnd_conflist_next(ci)) + vtp0_append(&omit_netnames, re_se_comp(ci->val.string[0])); + + t.Scale = 100; + for(net = pcb_net_first(&it, &pcb->netlist[PCB_NETLIST_EDITED]); net != NULL; net = pcb_net_next(&it)) { + shn_net_t shn; + char *atv; + + t.TextString = net->name; + pcb_text_bbox(pcb_font(pcb, 0, 1), &t); + + shn.w = t.BoundingBox.X2 - t.BoundingBox.X1; + shn.h = t.BoundingBox.Y2 - t.BoundingBox.Y1; + shn.show = 1; + + atv = pcb_attribute_get(&net->Attributes, "pcb-rnd::show_netname"); + if (atv != NULL) { + if ((strcmp(atv, "false") == 0) || (strcmp(atv, "off") == 0) || (strcmp(atv, "no") == 0)) + shn.show = 0; + } + + if (shn.show) { + for(n = 0; n < omit_netnames.used; n++) { + if (re_se_exec(omit_netnames.array[n], net->name)) { + shn.show = 0; + break; + } + } + } + + htshn_set(&shn_cache, net, shn); + } + + t.TextString = ""; + pcb_text_bbox(pcb_font(pcb, 0, 1), &t); + shn_nonet.w = t.BoundingBox.X2 - t.BoundingBox.X1; + shn_nonet.h = t.BoundingBox.Y2 - t.BoundingBox.Y1; + shn_nonet.show = 1; + + for(n = 0; n < omit_netnames.used; n++) + re_se_free(omit_netnames.array[n]); + vtp0_uninit(&omit_netnames); + + + shn_cache_uptodate = 1; +} + +static void show_netnames_invalidate(void) +{ + pcb_qry_uninit(&shn_qctx); +} + +static void show_netnames_inv_cache(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + shn_cache_uptodate = 0; +} + +static void show_netnames_brd_chg(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + if (conf_show_netnames.plugins.show_netnames.enable) + show_netnames_invalidate(); + shn_cache_uptodate = 0; +} + +static void *shn_render_cb(void *ctx, pcb_any_obj_t *obj) +{ + pcb_any_obj_t *term; + char tmp[128]; + const char *netname; + pcb_draw_info_t *info = ctx; + rnd_coord_t x, y, dx, dy; + rnd_font_t *font; + double rot, vx, vy, nx, ny, len, lscale; + shn_net_t *shn = NULL; + htshn_entry_t *e; + pcb_net_t *net = NULL; + + if (obj->type != PCB_OBJ_LINE) + return NULL; + + if (!shn_cache_uptodate) + shn_cache_update(PCB); + + term = pcb_qry_parent_net_term(&shn_qctx, obj); + if ((term != NULL) && (term->type == PCB_OBJ_NET_TERM)) + net = term->parent.net; + + if ((net == NULL) || (net->type != PCB_OBJ_NET)) { + if (conf_show_netnames.plugins.show_netnames.omit_nonets) + return NULL; + shn = &shn_nonet; + if (term != NULL) { + sprintf(tmp, "", term->ID); + netname = tmp; + } + else + netname = ""; + } + else { + e = htshn_getentry(&shn_cache, net); + if (e != NULL) + shn = &e->value; + netname = net->name; + } + + if ((shn == NULL) || !shn->show) + return NULL; + + pcb_obj_center(obj, &x, &y); + font = pcb_font(PCB, 0, 0); + + switch(obj->type) { + case PCB_OBJ_LINE: + { + pcb_line_t *l = (pcb_line_t *)obj; + + /* text height is 80% of trace thickness */ + lscale = (double)l->Thickness / (double)shn->h * 0.8; + + rot = atan2(l->Point2.Y - l->Point1.Y, l->Point2.X - l->Point1.X) * -RND_RAD_TO_DEG; + + /* offset the text for approx. center alignment */ + dx = -shn->w * lscale / 2; dy = -shn->h * lscale / 2; + vx = l->Point2.X - l->Point1.X; vy = l->Point2.Y - l->Point1.Y; + len = vx*vx + vy*vy; + + if (len != 0) { + len = sqrt(len); + + /* Don't print if label is longer than line's 80% */ + if (shn->w * lscale > len * 0.8) + return NULL; + + if (l != 0) { + vx /= len; + vy /= len; + nx = -vy; + ny = vx; + x += nx * dy + vx * dx; + y += ny * dy + vy * dx; + } + } + + pcb_text_draw_string(info, font, (const unsigned char *)netname, x, y, lscale, lscale, rot, 0, conf_core.appearance.label_thickness, 0, 0, 0, 0, PCB_TXT_TINY_HIDE, 0); + } + break; + default: + { + double scx, scy; + scx = (double)(obj->bbox_naked.X2 - obj->bbox_naked.X1) / (double)shn->w * 0.8; + scy = (double)(obj->bbox_naked.Y2 - obj->bbox_naked.Y1) / (double)shn->h * 0.8; + lscale = RND_MIN(scx, scy); + pcb_text_draw_string(info, font, (const unsigned char *)netname, x, y, lscale, lscale, 0.0, 0, conf_core.appearance.label_thickness, 0, 0, 0, 0, PCB_TXT_TINY_HIDE, 0); + } + } + return NULL; +} + +static void show_netnames_render(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[]) +{ + pcb_board_t *pcb; + pcb_draw_info_t *info; + rnd_box_t bx; + + if (!conf_show_netnames.plugins.show_netnames.enable || (rnd_gui == NULL) || (rnd_gui->coord_per_pix > conf_show_netnames.plugins.show_netnames.zoom_level)) + return; + + if (argv[2].type != RND_EVARG_PTR) + return; + + pcb = (pcb_board_t *)hidlib; + info = argv[2].d.p; + + if (shn_qctx.pcb != pcb) { + show_netnames_invalidate(); + shn_qctx.pcb = pcb; + } + + /* search negative box so anything touched is included */ + bx.X1 = info->drawn_area->X2; bx.Y1 = info->drawn_area->Y2; + bx.X2 = info->drawn_area->X1; bx.Y2 = info->drawn_area->Y1; + pcb_list_lyt_block_cb(pcb, PCB_LYT_COPPER, &bx, shn_render_cb, info); +} + +int pplg_check_ver_show_netnames(int ver_needed) { return 0; } + +void pplg_uninit_show_netnames(void) +{ + show_netnames_invalidate(); + + rnd_hid_menu_unload(rnd_gui, pcb_show_netnames_cookie); + rnd_event_unbind_allcookie(pcb_show_netnames_cookie); + rnd_remove_actions_by_cookie(pcb_show_netnames_cookie); + rnd_conf_plug_unreg("plugins/show_netnames/", show_netnames_conf_internal, pcb_show_netnames_cookie); + + if (shn_cache_inited) + htshn_uninit(&shn_cache); +} + +int pplg_init_show_netnames(void) +{ + RND_API_CHK_VER; + + rnd_conf_plug_reg(conf_show_netnames, show_netnames_conf_internal, pcb_show_netnames_cookie); +#define conf_reg(field,isarray,type_name,cpath,cname,desc,flags) \ + rnd_conf_reg_field(conf_show_netnames, field,isarray,type_name,cpath,cname,desc,flags); +#include "show_netnames_conf_fields.h" + + rnd_event_bind(PCB_EVENT_BOARD_EDITED, show_netnames_brd_chg, NULL, pcb_show_netnames_cookie); + rnd_event_bind(RND_EVENT_DESIGN_SET_CURRENT, show_netnames_brd_chg, NULL, pcb_show_netnames_cookie); + rnd_event_bind(RND_EVENT_GUI_DRAW_OVERLAY_XOR, show_netnames_render, NULL, pcb_show_netnames_cookie); + rnd_event_bind(PCB_EVENT_NETLIST_CHANGED, show_netnames_inv_cache, NULL, pcb_show_netnames_cookie); + rnd_event_bind(PCB_EVENT_FONT_CHANGED, show_netnames_inv_cache, NULL, pcb_show_netnames_cookie); + + rnd_hid_menu_load(rnd_gui, NULL, pcb_show_netnames_cookie, 150, NULL, 0, show_netnames_menu, "plugin: show_netnames"); + return 0; +}