/* File: check.c * * This file is part of XSCHEM, * a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit * simulation. * Copyright (C) 1998-2020 Stefan Frederik Schippers * * 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 */ #include "xschem.h" void check_touch(int i, int j, unsigned short *parallel,unsigned short *breaks, unsigned short *broken,unsigned short *touches, unsigned short *included, unsigned short *includes, double *xt, double *yt) { int touch1=0,touch2=0,touch3=0,touch4=0; double delta1x,delta1y,delta2x,delta2y; double x1,y1,x2,y2; x1=wire[i].x1; x2=wire[i].x2; y1=wire[i].y1; y2=wire[i].y2; delta1x = x2-x1;delta1y = y1-y2 ; delta2x = wire[j].x2-wire[j].x1;delta2y = wire[j].y1-wire[j].y2 ; *included = 0; *includes = 0; *touches = 0; *broken = 0; *breaks = 0; *parallel = (delta1x*delta2y == delta2x*delta1y ? 1:0); /* the order of the following 4 if(touch...) is not don't care !!! */ if(touch(wire[j].x1,wire[j].y1,wire[j].x2,wire[j].y2,x1,y1) ) { *touches = 1;touch3 =1; *xt = x1; *yt = y1; if((*xt > wire[j].x1 && *xt < wire[j].x2)|| (*yt > wire[j].y1 && *yt < wire[j].y2)) *breaks = 1; } if(touch(wire[j].x1,wire[j].y1,wire[j].x2,wire[j].y2,x2,y2) ) { *touches = 1;touch4 =1; *xt = x2; *yt = y2; if((*xt > wire[j].x1 && *xt < wire[j].x2)|| (*yt > wire[j].y1 && *yt < wire[j].y2)) *breaks = 1; } if(touch3 && touch4) *included = 1; if(touch(x1,y1,x2,y2,wire[j].x1,wire[j].y1) ) { *touches = 1;touch1=1; *xt = wire[j].x1; *yt = wire[j].y1; if((*xt > x1 && *xt < x2)||(*yt > y1 && *yt < y2)) *broken = 1; } if(touch(x1,y1,x2,y2,wire[j].x2,wire[j].y2) ) { *touches = 1;touch2=1; *xt = wire[j].x2; *yt = wire[j].y2; if((*xt > x1 && *xt < x2)||(*yt > y1 && *yt < y2)) *broken = 1; } if(touch1 && touch2) *includes = 1; dbg(2, "check_touch(): xt=%.16g, yt=%.16g\n",*xt, *yt); } void update_conn_cues(int draw_cues, int dr_win) { int k, i, l, sqx, sqy, save_draw; struct wireentry *wptr; double x0, y0; double x1, y1, x2, y2; struct wireentry *wireptr; hash_wires(); /* must be done also if lastwire==0 to clear wiretable */ if(!lastwire) return; if(!draw_dots) return; if(cadhalfdotsize*mooz<0.7) return; x1 = X_TO_XSCHEM(areax1); y1 = Y_TO_XSCHEM(areay1); x2 = X_TO_XSCHEM(areax2); y2 = Y_TO_XSCHEM(areay2); for(init_wire_iterator(x1, y1, x2, y2); ( wireptr = wire_iterator_next() ) ;) { k=wireptr->n; /* optimization when editing small areas (detailed zoom) of a huge schematic */ if(LINE_OUTSIDE(wire[k].x1, wire[k].y1, wire[k].x2, wire[k].y2, x1, y1, x2, y2)) continue; for(l = 0;l < 2;l++) { if(l==0 ) { if(wire[k].end1 !=-1) continue; /* 20181103 */ wire[k].end1=0; x0 = wire[k].x1; y0 = wire[k].y1; } else { if(wire[k].end2 !=-1) continue; /* 20181103 */ wire[k].end2=0; x0 = wire[k].x2; y0 = wire[k].y2; } get_square(x0, y0, &sqx, &sqy); for(wptr = wiretable[sqx][sqy] ; wptr ; wptr = wptr->next) { i = wptr->n; if(i == k) { continue; /* no check wire against itself */ } if( touch(wire[i].x1, wire[i].y1, wire[i].x2, wire[i].y2, x0,y0) ) { if( (x0 != wire[i].x1 && x0 != wire[i].x2) || (y0 != wire[i].y1 && y0 != wire[i].y2) ) { if(l == 0) wire[k].end1 += 2; else wire[k].end2 += 2; } else { if(l == 0) wire[k].end1 += 1; else wire[k].end2 += 1; } } } } } dbg(3, "update_conn_cues(): check3\n"); if(draw_cues) { save_draw = draw_window; draw_window = dr_win; for(init_wire_iterator(x1, y1, x2, y2); ( wireptr = wire_iterator_next() ) ;) { i = wireptr->n; /* optimization when editing small areas (detailed zoom) of a huge schematic */ if(LINE_OUTSIDE(wire[i].x1, wire[i].y1, wire[i].x2, wire[i].y2, x1, y1, x2, y2)) continue; if( wire[i].end1 >1 ) { /* 20150331 draw_dots */ filledarc(WIRELAYER, ADD, wire[i].x1, wire[i].y1, cadhalfdotsize, 0, 360); } if( wire[i].end2 >1 ) { /* 20150331 draw_dots */ filledarc(WIRELAYER, ADD, wire[i].x2, wire[i].y2, cadhalfdotsize, 0, 360); } } filledarc(WIRELAYER, END, 0.0, 0.0, 0.0, 0.0, 0.0); draw_window = save_draw; } } void trim_wires(void) /* wire coordinates must be ordered. */ { int j,i, changed; unsigned short parallel,breaks,broken,touches,included,includes; double xt=0,yt=0; int loops=0; do { loops++; for(i=0;irects[PINLAYER]) > 0 ) { for(r=0;rboxptr[PINLAYER]; x0=(rect[r].x1+rect[r].x2)/2; y0=(rect[r].y1+rect[r].y2)/2; rot=inst_ptr[k].rot; flip=inst_ptr[k].flip; ROTATION(0.0,0.0,x0,y0,rx1,ry1); x0=inst_ptr[k].x0+rx1; y0=inst_ptr[k].y0+ry1; get_square(x0, y0, &sqx, &sqy); for(wptr=wiretable[sqx][sqy]; wptr; wptr=wptr->next) { i = wptr->n; if( touch(wire[i].x1, wire[i].y1, wire[i].x2, wire[i].y2, x0,y0) ) { if( (x0!=wire[i].x1 && x0!=wire[i].x2) || (y0!=wire[i].y1 && y0!=wire[i].y2) ) { if(!changed) { push_undo(); changed=1;} check_wire_storage(); wire[lastwire].x1=wire[i].x1; wire[lastwire].y1=wire[i].y1; wire[lastwire].x2=x0; wire[lastwire].y2=y0; wire[lastwire].sel=SELECTED; wire[lastwire].prop_ptr=NULL; my_strdup(31, &wire[lastwire].prop_ptr, wire[i].prop_ptr); if(!strcmp(get_tok_value(wire[lastwire].prop_ptr,"bus",0), "true")) /* 20171201 */ wire[lastwire].bus=1; else wire[lastwire].bus=0; wire[lastwire].node=NULL; hash_wire(XINSERT, lastwire); my_strdup(32, &wire[lastwire].node, wire[i].node); need_rebuild_selected_array=1; lastwire++; wire[i].x1 = x0; wire[i].y1 = y0; } } } } } } /* prepared_hash_wires=0; */ /* hash_wires(); */ rebuild_selected_array(); for(j=0;jnext) { i = wptr->n; /* printf("check wire %d to wire %d\n", k, i); */ if(i==k) { continue; /* no check wire against itself */ } /* printf(" i=%d, x1=%g, y1=%g x2=%g, y2=%g\n", i, wire[i].x1, wire[i].y1, wire[i].x2, wire[i].y2); */ if( touch(wire[i].x1, wire[i].y1, wire[i].x2, wire[i].y2, x0,y0) ) { if( (x0!=wire[i].x1 && x0!=wire[i].x2) || (y0!=wire[i].y1 && y0!=wire[i].y2) ) { /* printf("touch in mid point: %d\n", l+1); */ if(!changed) { push_undo(); changed=1;} check_wire_storage(); wire[lastwire].x1=wire[i].x1; wire[lastwire].y1=wire[i].y1; wire[lastwire].x2=x0; wire[lastwire].y2=y0; wire[lastwire].sel=SELECTED; wire[lastwire].prop_ptr=NULL; my_strdup(33, &wire[lastwire].prop_ptr, wire[i].prop_ptr); if(!strcmp(get_tok_value(wire[lastwire].prop_ptr,"bus",0), "true")) /* 20171201 */ wire[lastwire].bus=1; else wire[lastwire].bus=0; wire[lastwire].node=NULL; hash_wire(XINSERT, lastwire); need_rebuild_selected_array=1; lastwire++; wire[i].x1 = x0; wire[i].y1 = y0; } } } } } set_modify(1); prepared_netlist_structs=0; prepared_hilight_structs=0; prepared_hash_wires=0; /*update_conn_cues(0, 0); */ }