Index: trunk/src/find_misc.c =================================================================== --- trunk/src/find_misc.c (revision 21905) +++ trunk/src/find_misc.c (nonexistent) @@ -1,458 +0,0 @@ -/* - * - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * (this file is based on PCB, interactive printed circuit board design) - * Copyright (C) 1994,1995,1996, 2005 Thomas Nau - * - * 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 St, 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 "change.h" - -#include "obj_arc_draw.h" -#include "obj_rat_draw.h" -#include "obj_line_draw.h" -#include "obj_poly_draw.h" -#include "obj_pstk_draw.h" - -static void DrawNewConnections(void); - -/* checks if all lists of new objects are handled */ -static pcb_bool ListsEmpty(pcb_bool AndRats) -{ - pcb_bool empty; - int i; - - empty = (PadstackList.Location >= PadstackList.Number); - if (AndRats) - empty = empty && (RatList.Location >= RatList.Number); - for (i = 0; i < pcb_max_layer && empty; i++) - empty = empty && LineList[i].Location >= LineList[i].Number - && ArcList[i].Location >= ArcList[i].Number && PolygonList[i].Location >= PolygonList[i].Number; - return empty; -} - -static void reassign_no_drc_flags(void) -{ - int layer; -TODO("layer: decide whether it is from attribute or not") - for (layer = 0; layer < pcb_max_layer; layer++) { - pcb_layer_t *l = LAYER_PTR(layer); - l->meta.real.no_drc = pcb_attribute_get(&l->Attributes, "PCB::skip-drc") != NULL; - } -} - - -/* loops till no more connections are found */ -static pcb_bool DoIt(pcb_bool AndRats, pcb_bool AndDraw) -{ - pcb_bool newone = pcb_false; - reassign_no_drc_flags(); - do { - /* lookup connections; these are the steps (2) to (4) - * from the description */ - newone = - LookupLOConnectionsToPSList(AndRats) - || LookupLOConnectionsToLOList(AndRats) - || LookupPSConnectionsToLOList(AndRats); - - if (AndDraw) - DrawNewConnections(); - } - while (!newone && !ListsEmpty(AndRats)); - if (AndDraw) - pcb_draw(); - return newone; -} - -/* draws all new connections which have been found since the routine was called the last time */ -static void DrawNewConnections(void) -{ - int i; - pcb_cardinal_t position; - - /* decrement 'i' to keep layerstack order */ - for (i = pcb_max_layer; i != -1; i--) { - pcb_cardinal_t layer = pcb_layer_stack[i]; - - if (PCB->Data->Layer[layer].meta.real.vis) { - /* draw all new lines */ - position = LineList[layer].DrawLocation; - for (; position < LineList[layer].Number; position++) - pcb_line_invalidate_draw(LAYER_PTR(layer), LINELIST_ENTRY(layer, position)); - LineList[layer].DrawLocation = LineList[layer].Number; - - /* draw all new arcs */ - position = ArcList[layer].DrawLocation; - for (; position < ArcList[layer].Number; position++) - pcb_arc_invalidate_draw(LAYER_PTR(layer), ARCLIST_ENTRY(layer, position)); - ArcList[layer].DrawLocation = ArcList[layer].Number; - - /* draw all new polygons */ - position = PolygonList[layer].DrawLocation; - for (; position < PolygonList[layer].Number; position++) - pcb_poly_invalidate_draw(LAYER_PTR(layer), POLYGONLIST_ENTRY(layer, position)); - PolygonList[layer].DrawLocation = PolygonList[layer].Number; - } - } - - /* draw all new Padstacks; 'PadstackList' holds a list of pointers to the - * sorted array pointers to padstack data - */ - while (PadstackList.DrawLocation < PadstackList.Number) { - pcb_pstk_t *ps = PADSTACKLIST_ENTRY(PadstackList.DrawLocation); - - if (PCB_FLAG_TEST(PCB_FLAG_TERMNAME, ps)) { - if (PCB->pstk_on) - pcb_pstk_invalidate_draw(ps); - } - else if (PCB->pstk_on) - pcb_pstk_invalidate_draw(ps); - PadstackList.DrawLocation++; - } - - /* draw the new rat-lines */ - if (PCB->RatOn) { - position = RatList.DrawLocation; - for (; position < RatList.Number; position++) - pcb_rat_invalidate_draw(RATLIST_ENTRY(position)); - RatList.DrawLocation = RatList.Number; - } -} - -/*--------------------------------------------------------------------------- - * add the starting object to the list of found objects - */ -static pcb_bool ListStart(pcb_any_obj_t *obj) -{ - DumpList(); - switch (obj->type) { - - case PCB_OBJ_PSTK: - { - if (ADD_PADSTACK_TO_LIST((pcb_pstk_t *)obj, 0, NULL, PCB_FCT_START, NULL)) - return pcb_true; - break; - } - - case PCB_OBJ_RAT: - { - if (ADD_RAT_TO_LIST((pcb_rat_t *)obj, 0, NULL, PCB_FCT_START, NULL)) - return pcb_true; - break; - } - - case PCB_OBJ_LINE: - { - pcb_layer_id_t layer = pcb_layer_id(PCB->Data, obj->parent.layer); - if (ADD_LINE_TO_LIST(layer, (pcb_line_t *)obj, 0, NULL, PCB_FCT_START, NULL)) - return pcb_true; - break; - } - - case PCB_OBJ_ARC: - { - pcb_layer_id_t layer = pcb_layer_id(PCB->Data, obj->parent.layer); - if (ADD_ARC_TO_LIST(layer, (pcb_arc_t *)obj, 0, NULL, PCB_FCT_START, NULL)) - return pcb_true; - break; - } - - case PCB_OBJ_POLY: - { - pcb_layer_id_t layer = pcb_layer_id(PCB->Data, obj->parent.layer); - if (ADD_POLYGON_TO_LIST(layer, (pcb_poly_t *)obj, 0, NULL, PCB_FCT_START, NULL)) - return pcb_true; - break; - } - - default: - assert(!"unhandled object type: can't start a find list from this\n"); - } - return pcb_false; -} - - -/* looks up all connections from the object at the given coordinates - * the TheFlag (normally 'PCB_FLAG_FOUND') is set for all objects found - * the objects are re-drawn if AndDraw is pcb_true - * also the action is marked as undoable if AndDraw is pcb_true */ -void pcb_lookup_conn(pcb_coord_t X, pcb_coord_t Y, pcb_bool AndDraw, pcb_coord_t Range, int which_flag) -{ - void *ptr1, *ptr2, *ptr3; - char *name; - int type; - - /* check if there are any pins or pads at that position */ - - reassign_no_drc_flags(); - - type = pcb_search_obj_by_location(PCB_LOOKUP_FIRST, &ptr1, &ptr2, &ptr3, X, Y, Range); - if (type == PCB_OBJ_VOID) { - type = pcb_search_obj_by_location(PCB_LOOKUP_MORE, &ptr1, &ptr2, &ptr3, X, Y, Range); - if (type == PCB_OBJ_VOID) - return; - if (type & PCB_SILK_TYPE) { - /* don't mess with non-conducting objects! */ - if (!(pcb_layer_flags_((pcb_layer_t *)ptr1) & PCB_LYT_COPPER) || ((pcb_layer_t *) ptr1)->meta.real.no_drc) - return; - } - } - else { - name = pcb_connection_name(ptr2); - if (name != NULL) - pcb_actionl("NetlistShow", name, NULL); - } - - TheFlag = which_flag; - User = AndDraw; - pcb_conn_lookup_init(); - - /* now add the object to the appropriate list and start scanning - * This is step (1) from the description - */ - ListStart(ptr2); - DoIt(pcb_true, AndDraw); - if (User) - pcb_undo_inc_serial(); - User = pcb_false; - - /* we are done */ - if (AndDraw) - pcb_draw(); - if (AndDraw && conf_core.editor.beep_when_finished) - pcb_gui->beep(); - pcb_conn_lookup_uninit(); -} - -void pcb_lookup_conn_by_pin(int type, void *ptr1) -{ - User = 0; - pcb_conn_lookup_init(); - ListStart(ptr1); - - DoIt(pcb_true, pcb_false); - - pcb_conn_lookup_uninit(); -} - -/* find connections for rats nesting assumes pcb_conn_lookup_init() has already been done */ -void pcb_rat_find_hook(pcb_any_obj_t *obj, pcb_bool undo, pcb_bool AndRats) -{ - User = undo; - DumpList(); - ListStart(obj); - DoIt(AndRats, pcb_false); - User = pcb_false; -} - -static pcb_bool pcb_reset_found_subc(pcb_subc_t *subc, pcb_bool AndDraw); - -/* resets all used flags of pins and vias */ -static pcb_bool pcb_reset_found_pins_vias_pads_(pcb_data_t *data, pcb_bool AndDraw) -{ - pcb_bool change = pcb_false; - - PCB_PADSTACK_LOOP(data); - { - if (PCB_FLAG_TEST(TheFlag, padstack)) { - if (AndDraw) - pcb_undo_add_obj_to_flag(padstack); - PCB_FLAG_CLEAR(TheFlag, padstack); - if (AndDraw) - pcb_pstk_invalidate_draw(padstack); - change = pcb_true; - } - } - PCB_END_LOOP; - PCB_SUBC_LOOP(data); - { - if (pcb_reset_found_subc(subc, AndDraw)) - change = pcb_true; - } - PCB_END_LOOP; - - return change; -} - -pcb_bool pcb_reset_found_pins_vias_pads(pcb_bool AndDraw) -{ - pcb_bool change = pcb_reset_found_pins_vias_pads_(PCB->Data, AndDraw); - - if (change) - pcb_board_set_changed_flag(pcb_true); - - return change; -} - -/* resets all used flags of LOs */ -static pcb_bool pcb_reset_found_lines_polys_(pcb_data_t *data, pcb_bool AndDraw) -{ - pcb_bool change = pcb_false; - - PCB_RAT_LOOP(data); - { - if (PCB_FLAG_TEST(TheFlag, line)) { - if (AndDraw) - pcb_undo_add_obj_to_flag(line); - PCB_FLAG_CLEAR(TheFlag, line); - if (AndDraw) - pcb_rat_invalidate_draw(line); - change = pcb_true; - } - } - PCB_END_LOOP; - PCB_LINE_COPPER_LOOP(data); - { - if (PCB_FLAG_TEST(TheFlag, line)) { - if (AndDraw) - pcb_undo_add_obj_to_flag(line); - PCB_FLAG_CLEAR(TheFlag, line); - if (AndDraw) - pcb_line_invalidate_draw(layer, line); - change = pcb_true; - } - } - PCB_ENDALL_LOOP; - PCB_ARC_COPPER_LOOP(data); - { - if (PCB_FLAG_TEST(TheFlag, arc)) { - if (AndDraw) - pcb_undo_add_obj_to_flag(arc); - PCB_FLAG_CLEAR(TheFlag, arc); - if (AndDraw) - pcb_arc_invalidate_draw(layer, arc); - change = pcb_true; - } - } - PCB_ENDALL_LOOP; - PCB_POLY_COPPER_LOOP(data); - { - if (PCB_FLAG_TEST(TheFlag, polygon)) { - if (AndDraw) - pcb_undo_add_obj_to_flag(polygon); - PCB_FLAG_CLEAR(TheFlag, polygon); - if (AndDraw) - pcb_poly_invalidate_draw(layer, polygon); - change = pcb_true; - } - } - PCB_ENDALL_LOOP; - - - PCB_SUBC_LOOP(data); - { - if (pcb_reset_found_subc(subc, AndDraw)) - change = pcb_true; - } - PCB_END_LOOP; - - return change; -} - -static pcb_bool pcb_reset_found_subc(pcb_subc_t *subc, pcb_bool AndDraw) -{ - pcb_bool res = pcb_false; - - if (pcb_reset_found_lines_polys_(subc->data, AndDraw)) - res = pcb_true; - - if (pcb_reset_found_pins_vias_pads_(subc->data, AndDraw)) - res = pcb_true; - - return res; -} - -pcb_bool pcb_reset_found_lines_polys(pcb_bool AndDraw) -{ - pcb_bool change = pcb_reset_found_lines_polys_(PCB->Data, AndDraw); - if (change) - pcb_board_set_changed_flag(pcb_true); - return change; - -} - - -/* resets all found connections */ -pcb_bool pcb_reset_conns(pcb_bool AndDraw) -{ - pcb_bool change = pcb_false; - - change = pcb_reset_found_pins_vias_pads(AndDraw) || change; - change = pcb_reset_found_lines_polys(AndDraw) || change; - - return change; -} - -/*---------------------------------------------------------------------------- - * Dumps the list contents - */ -static void DumpList(void) -{ - pcb_cardinal_t i; - - PadstackList.Number = 0; - PadstackList.Location = 0; - - for (i = 0; i < pcb_max_layer; i++) { - LineList[i].Location = 0; - LineList[i].DrawLocation = 0; - LineList[i].Number = 0; - ArcList[i].Location = 0; - ArcList[i].DrawLocation = 0; - ArcList[i].Number = 0; - PolygonList[i].Location = 0; - PolygonList[i].DrawLocation = 0; - PolygonList[i].Number = 0; - } - RatList.Number = 0; - RatList.Location = 0; - RatList.DrawLocation = 0; -} - -/*---------------------------------------------------------------------------- - * set up a temporary flag to use - */ -void pcb_save_find_flag(int NewFlag) -{ - OldFlag = TheFlag; - TheFlag = NewFlag; -} - -/*---------------------------------------------------------------------------- - * restore flag - */ -void pcb_restore_find_flag(void) -{ - TheFlag = OldFlag; -} - -void pcb_conn_lookup_init(void) -{ - pcb_layout_lookup_init(); -} - -void pcb_conn_lookup_uninit(void) -{ - pcb_layout_lookup_uninit(); -} Index: trunk/src/find_intconn.c =================================================================== --- trunk/src/find_intconn.c (revision 21905) +++ trunk/src/find_intconn.c (nonexistent) @@ -1,85 +0,0 @@ -/* - * - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * (this file is based on PCB, interactive printed circuit board design) - * Copyright (C) 1994,1995,1996, 2005 Thomas Nau - * Copyright (C) 2017 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 St, 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") - * - */ - -static void LOC_int_conn_subc(pcb_subc_t *s, int ic, int from_type, void *from_ptr) -{ - if (s == NULL) - return; - - PCB_PADSTACK_LOOP(s->data); - { - if ((padstack != from_ptr) && (padstack->term != NULL) && (padstack->intconn == ic) && (!PCB_FLAG_TEST(TheFlag, padstack))) { - PCB_FLAG_SET(PCB_FLAG_DRC_INTCONN, padstack); - ADD_PADSTACK_TO_LIST(padstack, from_type, from_ptr, PCB_FCT_INTCONN, NULL); - } - } - PCB_END_LOOP; - - PCB_LINE_COPPER_LOOP(s->data); - { - if ((line != from_ptr) && (line->term != NULL) && (line->intconn == ic) && (!PCB_FLAG_TEST(TheFlag, line))) { - PCB_FLAG_SET(PCB_FLAG_DRC_INTCONN, line); - ADD_LINE_TO_LIST(l, line, from_type, from_ptr, PCB_FCT_INTCONN, NULL); - } - } - PCB_ENDALL_LOOP; - - PCB_ARC_COPPER_LOOP(s->data); - { - if ((arc != from_ptr) && (arc->term != NULL) && (arc->intconn == ic) && (!PCB_FLAG_TEST(TheFlag, arc))) { - PCB_FLAG_SET(PCB_FLAG_DRC_INTCONN, arc); - ADD_ARC_TO_LIST(l, arc, from_type, from_ptr, PCB_FCT_INTCONN, NULL); - } - } - PCB_ENDALL_LOOP; - - PCB_POLY_COPPER_LOOP(s->data); - { - if ((polygon != from_ptr) && (polygon->term != NULL) && (polygon->intconn == ic) && (!PCB_FLAG_TEST(TheFlag, polygon))) { - PCB_FLAG_SET(PCB_FLAG_DRC_INTCONN, polygon); - ADD_POLYGON_TO_LIST(l, polygon, from_type, from_ptr, PCB_FCT_INTCONN, NULL); - } - } - PCB_ENDALL_LOOP; - -TODO("find: no find through text yet") -#if 0 - PCB_TEXT_COPPER_LOOP(s->data); - { - if ((text != from_ptr) && (text->term != NULL) && (text->intconn == ic) && (!PCB_FLAG_TEST(TheFlag, text))) { - PCB_FLAG_SET(PCB_FLAG_DRC_INTCONN, text); - ADD_TEXT_TO_LIST(l, text, from_type, from_ptr, PCB_FCT_INTCONN, NULL); - } - } - PCB_ENDALL_LOOP; -#endif -} - -#define INOCN(a,b) int_noconn((pcb_any_obj_t *)a, (pcb_any_obj_t *)b) Index: trunk/src/find_lookup.c =================================================================== --- trunk/src/find_lookup.c (revision 21905) +++ trunk/src/find_lookup.c (nonexistent) @@ -1,989 +0,0 @@ -/* - * - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * (this file is based on PCB, interactive printed circuit board design) - * Copyright (C) 1994,1995,1996, 2005 Thomas Nau - * - * 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 St, 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 "compat_nls.h" -#include "board.h" -#include "obj_subc_parent.h" - -static inline pcb_r_dir_t r_search_pt(pcb_rtree_t * rtree, const pcb_point_t * pt, - int radius, - pcb_r_dir_t (*region_in_search) (const pcb_box_t * region, void *cl), - pcb_r_dir_t (*rectangle_in_region) (const pcb_box_t * box, void *cl), void *closure, - int *num_found) -{ - pcb_box_t box; - - box.X1 = pt->X - radius; - box.X2 = pt->X + radius; - box.Y1 = pt->Y - radius; - box.Y2 = pt->Y + radius; - - return pcb_r_search(rtree, &box, region_in_search, rectangle_in_region, closure, num_found); -} - - -/* Connection lookup functions */ - -static pcb_bool ADD_PS_TO_LIST(pcb_pstk_t *ps, int from_type, void *from_ptr, pcb_found_conn_type_t type, void *orig_from) -{ - if (User) - pcb_undo_add_obj_to_flag(ps); - PCB_FLAG_SET(TheFlag, ps); - make_callback(PCB_OBJ_PSTK, ps, from_type, from_ptr, type); - PADSTACKLIST_ENTRY(PadstackList.Number) = ps; - PadstackList.Number++; -#ifdef DEBUG - if (PadstackList.Number > PadstackList.Size) - printf("ADD_PS_TO_LIST overflow! num=%d size=%d\n", PadstackList.Number, PadstackList.Size); -#endif - if (drc && !PCB_FLAG_TEST(PCB_FLAG_SELECTED, ps)) - return SetThing(ps, orig_from); - return pcb_false; -} - -static pcb_bool ADD_PADSTACK_TO_LIST(pcb_pstk_t *ps, int from_type, void *from_ptr, pcb_found_conn_type_t type, void *orig_from) -{ - if (User) - pcb_undo_add_obj_to_flag(ps); - PCB_FLAG_SET(TheFlag, ps); - make_callback(PCB_OBJ_PSTK, ps, from_type, from_ptr, type); - PADSTACKLIST_ENTRY(PadstackList.Number) = ps; - PadstackList.Number++; -#ifdef DEBUG - if (PadstackList.Number > PadstackList.Size) - printf("ADD_PADSTACK_TO_LIST overflow! num=%d size=%d\n", PVList.Number, PVList.Size); -#endif - if (drc && !PCB_FLAG_TEST(PCB_FLAG_SELECTED, ps) && (ps->parent.data->parent_type == PCB_PARENT_SUBC)) - return SetThing(ps, orig_from); - return pcb_false; -} - -static pcb_bool ADD_LINE_TO_LIST(pcb_layer_id_t L, pcb_line_t *Ptr, int from_type, void *from_ptr, pcb_found_conn_type_t type, void *orig_from) -{ - if (LineList[L].Data == NULL) - return pcb_false; - if (User) - pcb_undo_add_obj_to_flag(Ptr); - PCB_FLAG_SET(TheFlag, (Ptr)); - make_callback(PCB_OBJ_LINE, Ptr, from_type, from_ptr, type); - LINELIST_ENTRY((L), LineList[(L)].Number) = (Ptr); - LineList[(L)].Number++; -#ifdef DEBUG - if (LineList[(L)].Number > LineList[(L)].Size) - printf("ADD_LINE_TO_LIST overflow! lay=%d, num=%d size=%d\n", L, LineList[(L)].Number, LineList[(L)].Size); -#endif - if (drc && !PCB_FLAG_TEST(PCB_FLAG_SELECTED, (Ptr))) - return SetThing(Ptr, orig_from); - return pcb_false; -} - -static pcb_bool ADD_ARC_TO_LIST(pcb_cardinal_t L, pcb_arc_t *Ptr, int from_type, void *from_ptr, pcb_found_conn_type_t type, void *orig_from) -{ - if (ArcList[L].Data == NULL) - return pcb_false; - - if (User) - pcb_undo_add_obj_to_flag(Ptr); - PCB_FLAG_SET(TheFlag, (Ptr)); - make_callback(PCB_OBJ_ARC, Ptr, from_type, from_ptr, type); - ARCLIST_ENTRY((L), ArcList[(L)].Number) = (Ptr); - ArcList[(L)].Number++; -#ifdef DEBUG - if (ArcList[(L)].Number > ArcList[(L)].Size) - printf("ADD_ARC_TO_LIST overflow! lay=%d, num=%d size=%d\n", L, ArcList[(L)].Number, ArcList[(L)].Size); -#endif - if (drc && !PCB_FLAG_TEST(PCB_FLAG_SELECTED, (Ptr))) - return SetThing(Ptr, orig_from); - return pcb_false; -} - -static pcb_bool ADD_RAT_TO_LIST(pcb_rat_t *Ptr, int from_type, void *from_ptr, pcb_found_conn_type_t type, void *orig_from) -{ - if (User) - pcb_undo_add_obj_to_flag(Ptr); - PCB_FLAG_SET(TheFlag, (Ptr)); - make_callback(PCB_OBJ_RAT, Ptr, from_type, from_ptr, type); - RATLIST_ENTRY(RatList.Number) = (Ptr); - RatList.Number++; -#ifdef DEBUG - if (RatList.Number > RatList.Size) - printf("ADD_RAT_TO_LIST overflow! num=%d size=%d\n", RatList.Number, RatList.Size); -#endif - if (drc && !PCB_FLAG_TEST(PCB_FLAG_SELECTED, (Ptr))) - return SetThing(Ptr, orig_from); - return pcb_false; -} - -static pcb_bool ADD_POLYGON_TO_LIST(pcb_cardinal_t L, pcb_poly_t *Ptr, int from_type, void *from_ptr, pcb_found_conn_type_t type, void *orig_from) -{ - if (PolygonList[L].Data == NULL) - return pcb_false; - - if (User) - pcb_undo_add_obj_to_flag(Ptr); - PCB_FLAG_SET(TheFlag, (Ptr)); - make_callback(PCB_OBJ_POLY, Ptr, from_type, from_ptr, type); - POLYGONLIST_ENTRY((L), PolygonList[(L)].Number) = (Ptr); - PolygonList[(L)].Number++; -#ifdef DEBUG - if (PolygonList[(L)].Number > PolygonList[(L)].Size) - printf("ADD_ARC_TO_LIST overflow! lay=%d, num=%d size=%d\n", L, PolygonList[(L)].Number, PolygonList[(L)].Size); -#endif - if (drc && !PCB_FLAG_TEST(PCB_FLAG_SELECTED, (Ptr))) - return SetThing(Ptr, orig_from); - return pcb_false; -} - -pcb_bool SetThing(void *obj1, void *obj2) -{ - pcb_found_obj1 = obj1; - pcb_found_obj2 = obj2; - return pcb_true; -} - -#include "find_intconn.c" - -void pcb_layout_lookup_uninit(void) -{ - pcb_cardinal_t i; - - for (i = 0; i < pcb_max_layer; i++) { - free(LineList[i].Data); - LineList[i].Data = NULL; - free(ArcList[i].Data); - ArcList[i].Data = NULL; - free(PolygonList[i].Data); - PolygonList[i].Data = NULL; - } - free(RatList.Data); - free(PadstackList.Data); - RatList.Data = NULL; - PadstackList.Data = NULL; -} - -/* allocates memory for component related stacks ... - * initializes index and sorts it by X1 and X2 */ -static void pcb_layout_lookup_init(void) -{ - pcb_layer_id_t i; - - /* initialize line arc and polygon data */ - for(i = 0; i < pcb_max_layer; i++) { - pcb_layer_t *layer = LAYER_PTR(i); - - if (pcb_layer_flags(PCB, i) & PCB_LYT_COPPER) { - - if ((layer->line_tree != NULL) && (layer->line_tree->size > 0)) { - LineList[i].Size = layer->line_tree->size; - LineList[i].Data = (void **) calloc(LineList[i].Size, sizeof(pcb_line_t *)); - } - if ((layer->arc_tree != NULL) && (layer->arc_tree->size > 0)) { - ArcList[i].Size = layer->arc_tree->size; - ArcList[i].Data = (void **) calloc(ArcList[i].Size, sizeof(pcb_arc_t *)); - } - if ((layer->polygon_tree != NULL) && (layer->polygon_tree->size > 0)) { - PolygonList[i].Size = layer->polygon_tree->size; - PolygonList[i].Data = (void **) calloc(PolygonList[i].Size, sizeof(pcb_poly_t *)); - } - - } - - /* clear some struct members */ - LineList[i].Location = 0; - LineList[i].DrawLocation = 0; - LineList[i].Number = 0; - ArcList[i].Location = 0; - ArcList[i].DrawLocation = 0; - ArcList[i].Number = 0; - PolygonList[i].Location = 0; - PolygonList[i].DrawLocation = 0; - PolygonList[i].Number = 0; - } - - if (PCB->Data->padstack_tree) - TotalPs = PCB->Data->padstack_tree->size; - else - TotalPs = 0; - /* allocate memory for 'new padstack to check' list and clear struct */ - PadstackList.Data = (void **) calloc(TotalPs, sizeof(pcb_pstk_t *)); - PadstackList.Size = TotalPs; - PadstackList.Location = 0; - PadstackList.DrawLocation = 0; - PadstackList.Number = 0; - /* Initialize ratline data */ - RatList.Size = ratlist_length(&PCB->Data->Rat); - RatList.Data = (void **) calloc(RatList.Size, sizeof(pcb_rat_t *)); - RatList.Location = 0; - RatList.DrawLocation = 0; - RatList.Number = 0; -} - -struct lo_info { - pcb_layer_id_t layer; - pcb_line_t line; - pcb_arc_t arc; - pcb_poly_t polygon; - pcb_rat_t rat; - - pcb_layer_id_t *orig_layer; - pcb_line_t *orig_line; - pcb_arc_t *orig_arc; - pcb_poly_t *orig_polygon; - pcb_rat_t *orig_rat; - - jmp_buf env; -}; - -struct ps_info { - pcb_layer_id_t layer; - pcb_pstk_t ps; - pcb_pstk_t *orig_ps; - jmp_buf env; -}; - -static pcb_r_dir_t LOCtoPSline_callback(const pcb_box_t * b, void *cl) -{ - pcb_line_t *line = (pcb_line_t *) b; - struct ps_info *i = (struct ps_info *) cl; - - if (!PCB_FLAG_TEST(TheFlag, line) && pcb_isc_pstk_line(&i->ps, line) && !INOCN(&i->ps, line)) { - if (ADD_LINE_TO_LIST(i->layer, line, PCB_OBJ_PSTK, &i->ps, PCB_FCT_COPPER, i->orig_ps)) - longjmp(i->env, 1); - } - return PCB_R_DIR_NOT_FOUND; -} - -static pcb_r_dir_t LOCtoPSarc_callback(const pcb_box_t * b, void *cl) -{ - pcb_arc_t *arc = (pcb_arc_t *) b; - struct ps_info *i = (struct ps_info *) cl; - - if (!PCB_FLAG_TEST(TheFlag, arc) && pcb_isc_pstk_arc(&i->ps, arc) && !INOCN(&i->ps, arc)) { - if (ADD_ARC_TO_LIST(i->layer, arc, PCB_OBJ_PSTK, &i->ps, PCB_FCT_COPPER, i->orig_ps)) - longjmp(i->env, 1); - } - return PCB_R_DIR_NOT_FOUND; -} - -static pcb_r_dir_t LOCtoPSrat_callback(const pcb_box_t * b, void *cl) -{ - pcb_rat_t *rat = (pcb_rat_t *) b; - struct ps_info *i = (struct ps_info *) cl; - - if (!PCB_FLAG_TEST(TheFlag, rat) && pcb_isc_pstk_rat(&i->ps, rat) && ADD_RAT_TO_LIST(rat, PCB_OBJ_PSTK, &i->ps, PCB_FCT_RAT, i->orig_ps)) - longjmp(i->env, 1); - return PCB_R_DIR_NOT_FOUND; -} - -static pcb_r_dir_t LOCtoPSpoly_callback(const pcb_box_t * b, void *cl) -{ - pcb_poly_t *polygon = (pcb_poly_t *) b; - struct ps_info *i = (struct ps_info *) cl; - - if (!PCB_FLAG_TEST(TheFlag, polygon) && pcb_isc_pstk_poly(&i->ps, polygon) && !INOCN(&i->ps, polygon)) { - if (ADD_POLYGON_TO_LIST(i->layer, polygon, PCB_OBJ_PSTK, &i->ps, PCB_FCT_COPPER, i->orig_ps)) - longjmp(i->env, 1); - } - - return PCB_R_DIR_NOT_FOUND; -} - -static pcb_r_dir_t PStoPS_callback(const pcb_box_t *b, void *cl) -{ - pcb_pstk_t *ps2 = (pcb_pstk_t *)b; - struct ps_info *i = (struct ps_info *)cl; - - if (!PCB_FLAG_TEST(TheFlag, ps2) && pcb_isc_pstk_pstk(&i->ps, ps2) && !INOCN(&i->ps, ps2)) { - if (ADD_PADSTACK_TO_LIST(ps2, PCB_OBJ_PSTK, &i->ps, PCB_FCT_COPPER, i->orig_ps)) - longjmp(i->env, 1); - } - - return PCB_R_DIR_NOT_FOUND; -} - -/* checks if a padstack is connected to LOs, if it is, the LO is added to - * the appropriate list and the 'used' flag is set */ -static pcb_bool LookupLOConnectionsToPSList(pcb_bool AndRats) -{ - pcb_cardinal_t layer; - struct ps_info info; - pcb_pstk_t *orig_ps; - - /* loop over all PVs currently on list */ - while (PadstackList.Location < PadstackList.Number) { - /* get pointer to data */ - orig_ps = (PADSTACKLIST_ENTRY(PadstackList.Location)); - info.ps = *orig_ps; - info.orig_ps = orig_ps; - EXPAND_BOUNDS(&info.ps); - - /* subc intconn jumps */ - if ((orig_ps->term != NULL) && (orig_ps->intconn > 0)) - LOC_int_conn_subc(pcb_gobj_parent_subc(orig_ps->parent_type, &orig_ps->parent), orig_ps->intconn, PCB_OBJ_PSTK, orig_ps); - - /* now all lines, arcs and polygons of the several layers */ - for(layer = 0; layer < pcb_max_layer; layer++) { - if (!(pcb_layer_flags(PCB, layer) & PCB_LYT_COPPER)) - continue; - if (LAYER_PTR(layer)->meta.real.no_drc) - continue; - info.layer = layer; - /* add touching lines */ - if (setjmp(info.env) == 0) - pcb_r_search(LAYER_PTR(layer)->line_tree, (pcb_box_t *) & info.ps, NULL, LOCtoPSline_callback, &info, NULL); - else - return pcb_true; - /* add touching arcs */ - if (setjmp(info.env) == 0) - pcb_r_search(LAYER_PTR(layer)->arc_tree, (pcb_box_t *) & info.ps, NULL, LOCtoPSarc_callback, &info, NULL); - else - return pcb_true; - /* check all polygons */ - if (setjmp(info.env) == 0) - pcb_r_search(LAYER_PTR(layer)->polygon_tree, (pcb_box_t *) & info.ps, NULL, LOCtoPSpoly_callback, &info, NULL); - else - return pcb_true; - } - - /* Check for connections to other padstacks */ - if (setjmp(info.env) == 0) - pcb_r_search(PCB->Data->padstack_tree, (pcb_box_t *) & info.ps, NULL, PStoPS_callback, &info, NULL); - else - return pcb_true; - - /* Check for rat-lines that may intersect the PV */ - if (AndRats) { - if (setjmp(info.env) == 0) - pcb_r_search(PCB->Data->rat_tree, (pcb_box_t *) & info.ps, NULL, LOCtoPSrat_callback, &info, NULL); - else - return pcb_true; - } - PadstackList.Location++; - } - return pcb_false; -} - -/* find all connections between LO at the current list position and new LOs */ -static pcb_bool LookupLOConnectionsToLOList(pcb_bool AndRats) -{ - pcb_bool done; - pcb_layer_id_t layer; - pcb_layergrp_id_t group; - pcb_cardinal_t i, ratposition, lineposition[PCB_MAX_LAYER], polyposition[PCB_MAX_LAYER], arcposition[PCB_MAX_LAYER]; - - /* copy the current LO list positions; the original data is changed - * by 'LookupPVPSConnectionsToLOList()' which has to check the same - * list entries plus the new ones - */ - for (i = 0; i < pcb_max_layer; i++) { - lineposition[i] = LineList[i].Location; - polyposition[i] = PolygonList[i].Location; - arcposition[i] = ArcList[i].Location; - } - ratposition = RatList.Location; - - /* loop over all new LOs in the list; recurse until no - * more new connections in the layergroup were found - */ - do { - pcb_cardinal_t *position; - - if (AndRats) { - position = &ratposition; - for (; *position < RatList.Number; (*position)++) { - group = RATLIST_ENTRY(*position)->group1; - if (LookupLOConnectionsToRatEnd(&(RATLIST_ENTRY(*position)->Point1), group)) - return pcb_true; - group = RATLIST_ENTRY(*position)->group2; - if (LookupLOConnectionsToRatEnd(&(RATLIST_ENTRY(*position)->Point2), group)) - return pcb_true; - } - } - /* loop over all layergroups */ - for (group = 0; group < PCB->LayerGroups.len; group++) { - pcb_cardinal_t entry; - - for (entry = 0; entry < PCB->LayerGroups.grp[group].len; entry++) { - layer = PCB->LayerGroups.grp[group].lid[entry]; - - /* be aware that the layer number equal pcb_max_layer - * and pcb_max_layer+1 have a special meaning for pads - */ - /* try all new lines */ - position = &lineposition[layer]; - for (; *position < LineList[layer].Number; (*position)++) - if (LookupLOConnectionsToLine(LINELIST_ENTRY(layer, *position), group, pcb_true)) - return pcb_true; - - /* try all new arcs */ - position = &arcposition[layer]; - for (; *position < ArcList[layer].Number; (*position)++) - if (LookupLOConnectionsToArc(ARCLIST_ENTRY(layer, *position), group)) - return pcb_true; - - /* try all new polygons */ - position = &polyposition[layer]; - for (; *position < PolygonList[layer].Number; (*position)++) - if (LookupLOConnectionsToPolygon(POLYGONLIST_ENTRY(layer, *position), group)) - return pcb_true; - } - } - - /* check if all lists are done; Later for-loops - * may have changed the prior lists - */ - done = !AndRats || ratposition >= RatList.Number; - for (layer = 0; layer < pcb_max_layer; layer++) { - done = done && - lineposition[layer] >= LineList[layer].Number - && arcposition[layer] >= ArcList[layer].Number && polyposition[layer] >= PolygonList[layer].Number; - } - } while (!done); - return pcb_false; -} - -static pcb_r_dir_t ps_line_callback(const pcb_box_t * b, void *cl) -{ - pcb_pstk_t *ps = (pcb_pstk_t *) b; - struct lo_info *i = (struct lo_info *) cl; - - if (!PCB_FLAG_TEST(TheFlag, ps) && pcb_isc_pstk_line(ps, &i->line) && !INOCN(ps, &i->line)) { - if (ADD_PS_TO_LIST(ps, PCB_OBJ_LINE, &i->line, PCB_FCT_COPPER, i->orig_line)) - longjmp(i->env, 1); - } - return PCB_R_DIR_NOT_FOUND; -} - -static pcb_r_dir_t ps_arc_callback(const pcb_box_t * b, void *cl) -{ - pcb_pstk_t *ps = (pcb_pstk_t *) b; - struct lo_info *i = (struct lo_info *) cl; - - if (!PCB_FLAG_TEST(TheFlag, ps) && pcb_isc_pstk_arc(ps, &i->arc) && !INOCN(ps, &i->arc)) { - if (ADD_PS_TO_LIST(ps, PCB_OBJ_ARC, &i->arc, PCB_FCT_COPPER, i->orig_arc)) - longjmp(i->env, 1); - } - return PCB_R_DIR_NOT_FOUND; -} - -static pcb_r_dir_t ps_poly_callback(const pcb_box_t * b, void *cl) -{ - pcb_pstk_t *ps = (pcb_pstk_t *) b; - struct lo_info *i = (struct lo_info *) cl; - - if (!PCB_FLAG_TEST(TheFlag, ps) && pcb_isc_pstk_poly(ps, &i->polygon) && !INOCN(ps, &i->polygon)) { - if (ADD_PS_TO_LIST(ps, PCB_OBJ_POLY, &i->polygon, PCB_FCT_COPPER, i->orig_polygon)) - longjmp(i->env, 1); - } - - return PCB_R_DIR_NOT_FOUND; -} - -static pcb_r_dir_t ps_rat_callback(const pcb_box_t * b, void *cl) -{ - pcb_pstk_t *ps = (pcb_pstk_t *) b; - struct lo_info *i = (struct lo_info *) cl; - - /* rats can't cause DRC so there is no early exit */ - if (!PCB_FLAG_TEST(TheFlag, ps) && pcb_isc_pstk_rat(ps, &i->rat)) - ADD_PS_TO_LIST(ps, PCB_OBJ_RAT, &i->rat, PCB_FCT_RAT, i->orig_rat); - return PCB_R_DIR_NOT_FOUND; -} - -/* searches for new PVs and padstacks that are connected to NEW LOs on the list - * This routine updates the position counter of the lists too. */ -static pcb_bool LookupPSConnectionsToLOList(pcb_bool AndRats) -{ - pcb_layer_id_t layer; - struct lo_info info; - - /* loop over all layers */ - for(layer = 0; layer < pcb_max_layer; layer++) { - if (!(pcb_layer_flags(PCB, layer) & PCB_LYT_COPPER)) - continue; - if (LAYER_PTR(layer)->meta.real.no_drc) - continue; - /* do nothing if there are no PV's */ - if (TotalPs == 0) { - LineList[layer].Location = LineList[layer].Number; - ArcList[layer].Location = ArcList[layer].Number; - PolygonList[layer].Location = PolygonList[layer].Number; - continue; - } - - /* check all lines */ - while (LineList[layer].Location < LineList[layer].Number) { - pcb_line_t *orig_line = (LINELIST_ENTRY(layer, LineList[layer].Location)); - info.line = *orig_line; - info.orig_line = orig_line; - EXPAND_BOUNDS(&info.line); - - /* subc intconn jumps */ - if ((orig_line->term != NULL) && (orig_line->intconn > 0)) - LOC_int_conn_subc(pcb_lobj_parent_subc(orig_line->parent_type, &orig_line->parent), orig_line->intconn, PCB_OBJ_LINE, orig_line); - - if (setjmp(info.env) == 0) - pcb_r_search(PCB->Data->padstack_tree, (pcb_box_t *) & info.line, NULL, ps_line_callback, &info, NULL); - else - return pcb_true; - LineList[layer].Location++; - } - - /* check all arcs */ - while (ArcList[layer].Location < ArcList[layer].Number) { - pcb_arc_t *orig_arc = (ARCLIST_ENTRY(layer, ArcList[layer].Location)); - info.arc = *orig_arc; - info.orig_arc = orig_arc; - EXPAND_BOUNDS(&info.arc); - - /* subc intconn jumps */ - if ((orig_arc->term != NULL) && (orig_arc->intconn > 0)) - LOC_int_conn_subc(pcb_lobj_parent_subc(orig_arc->parent_type, &orig_arc->parent), orig_arc->intconn, PCB_OBJ_LINE, orig_arc); - - if (setjmp(info.env) == 0) - pcb_r_search(PCB->Data->padstack_tree, (pcb_box_t *) & info.arc, NULL, ps_arc_callback, &info, NULL); - else - return pcb_true; - ArcList[layer].Location++; - } - - /* now all polygons */ - info.layer = layer; - while (PolygonList[layer].Location < PolygonList[layer].Number) { - pcb_poly_t *orig_poly = (POLYGONLIST_ENTRY(layer, PolygonList[layer].Location)); - info.polygon = *orig_poly; - info.orig_polygon = orig_poly; - EXPAND_BOUNDS(&info.polygon); - - /* subc intconn jumps */ - if ((orig_poly->term != NULL) && (orig_poly->intconn > 0)) - LOC_int_conn_subc(pcb_lobj_parent_subc(orig_poly->parent_type, &orig_poly->parent), orig_poly->intconn, PCB_OBJ_LINE, orig_poly); - - if (setjmp(info.env) == 0) - pcb_r_search(PCB->Data->padstack_tree, (pcb_box_t *) & info.polygon, NULL, ps_poly_callback, &info, NULL); - else - return pcb_true; - PolygonList[layer].Location++; - } - } - - /* do nothing if there are no PS's */ - if (TotalPs == 0) - RatList.Location = RatList.Number; - - /* check all rat-lines */ - if (AndRats) { - while (RatList.Location < RatList.Number) { - info.rat = *(RATLIST_ENTRY(RatList.Location)); - info.orig_rat = (RATLIST_ENTRY(RatList.Location)); - r_search_pt(PCB->Data->padstack_tree, &info.rat.Point1, 1, NULL, ps_rat_callback, &info, NULL); - r_search_pt(PCB->Data->padstack_tree, &info.rat.Point2, 1, NULL, ps_rat_callback, &info, NULL); - - RatList.Location++; - } - } - return pcb_false; -} - -static pcb_r_dir_t LOCtoArcLine_callback(const pcb_box_t * b, void *cl) -{ - pcb_line_t *line = (pcb_line_t *) b; - struct lo_info *i = (struct lo_info *) cl; - - if (!PCB_FLAG_TEST(TheFlag, line) && pcb_isc_line_arc(line, &i->arc) && !INOCN(line, &i->arc)) { - if (ADD_LINE_TO_LIST(i->layer, line, PCB_OBJ_ARC, &i->arc, PCB_FCT_COPPER, i->orig_arc)) - longjmp(i->env, 1); - } - return PCB_R_DIR_NOT_FOUND; -} - -static pcb_r_dir_t LOCtoArcArc_callback(const pcb_box_t * b, void *cl) -{ - pcb_arc_t *arc = (pcb_arc_t *) b; - struct lo_info *i = (struct lo_info *) cl; - - if (!arc->Thickness) - return 0; - if (!PCB_FLAG_TEST(TheFlag, arc) && pcb_isc_arc_arc(&i->arc, arc) && !INOCN(&i->arc, arc)) { - if (ADD_ARC_TO_LIST(i->layer, arc, PCB_OBJ_ARC, &i->arc, PCB_FCT_COPPER, i->orig_arc)) - longjmp(i->env, 1); - } - return PCB_R_DIR_NOT_FOUND; -} - -static pcb_r_dir_t LOCtoArcRat_callback(const pcb_box_t *b, void *cl) -{ - pcb_rat_t *rat = (pcb_rat_t *)b; - struct lo_info *i = (struct lo_info *)cl; - - if (!PCB_FLAG_TEST(TheFlag, rat)) { - if ((rat->group1 == i->layer) - && pcb_isc_ratp_arc(&rat->Point1, &i->arc)) { - if (ADD_RAT_TO_LIST(rat, PCB_OBJ_ARC, &i->arc, PCB_FCT_RAT, i->orig_arc)) - longjmp(i->env, 1); - } - else if ((rat->group2 == i->layer) - && pcb_isc_ratp_arc(&rat->Point2, &i->arc)) { - if (ADD_RAT_TO_LIST(rat, PCB_OBJ_ARC, &i->arc, PCB_FCT_RAT, i->orig_arc)) - longjmp(i->env, 1); - } - } - return PCB_R_DIR_NOT_FOUND; -} - -/* searches all LOs that are connected to the given arc on the given - * layergroup. All found connections are added to the list - * - * the notation that is used is: - * Xij means Xj at arc i */ -static pcb_bool LookupLOConnectionsToArc(pcb_arc_t *Arc, pcb_cardinal_t LayerGroup) -{ - pcb_cardinal_t entry; - struct lo_info info; - - info.arc = *Arc; - info.orig_arc = Arc; - EXPAND_BOUNDS(&info.arc); - - - /* loop over all layers of the group */ - for (entry = 0; entry < PCB->LayerGroups.grp[LayerGroup].len; entry++) { - pcb_layer_id_t layer; - - layer = PCB->LayerGroups.grp[LayerGroup].lid[entry]; - - info.layer = LayerGroup; - - /* add the new rat lines */ - if (setjmp(info.env) == 0) - pcb_r_search(PCB->Data->rat_tree, &info.arc.BoundingBox, NULL, LOCtoArcRat_callback, &info, NULL); - else - return pcb_true; - - info.layer = layer; - - /* add arcs */ - if (setjmp(info.env) == 0) - pcb_r_search(LAYER_PTR(layer)->line_tree, &info.arc.BoundingBox, NULL, LOCtoArcLine_callback, &info, NULL); - else - return pcb_true; - - if (setjmp(info.env) == 0) - pcb_r_search(LAYER_PTR(layer)->arc_tree, &info.arc.BoundingBox, NULL, LOCtoArcArc_callback, &info, NULL); - else - return pcb_true; - - /* now check all polygons */ - { - pcb_rtree_it_t it; - pcb_box_t *b; - for(b = pcb_r_first(PCB->Data->Layer[layer].polygon_tree, &it); b != NULL; b = pcb_r_next(&it)) { - pcb_poly_t *polygon = (pcb_poly_t *)b; - if (!PCB_FLAG_TEST(TheFlag, polygon) && pcb_isc_arc_poly(Arc, polygon) - && ADD_POLYGON_TO_LIST(layer, polygon, PCB_OBJ_ARC, Arc, PCB_FCT_COPPER, Arc)) - return pcb_true; - } - pcb_r_end(&it); - } - } - - return pcb_false; -} - -static pcb_r_dir_t LOCtoLineLine_callback(const pcb_box_t * b, void *cl) -{ - pcb_line_t *line = (pcb_line_t *) b; - struct lo_info *i = (struct lo_info *) cl; - - if (!PCB_FLAG_TEST(TheFlag, line) && pcb_isc_line_line(&i->line, line) && !INOCN(&i->line, line)) { - if (ADD_LINE_TO_LIST(i->layer, line, PCB_OBJ_LINE, &i->line, PCB_FCT_COPPER, i->orig_line)) - longjmp(i->env, 1); - } - return PCB_R_DIR_NOT_FOUND; -} - -static pcb_r_dir_t LOCtoLineArc_callback(const pcb_box_t * b, void *cl) -{ - pcb_arc_t *arc = (pcb_arc_t *) b; - struct lo_info *i = (struct lo_info *) cl; - - if (!arc->Thickness) - return 0; - if (!PCB_FLAG_TEST(TheFlag, arc) && pcb_isc_line_arc(&i->line, arc) && !INOCN(&i->line, arc)) { - if (ADD_ARC_TO_LIST(i->layer, arc, PCB_OBJ_LINE, &i->line, PCB_FCT_COPPER, i->orig_line)) - longjmp(i->env, 1); - } - return PCB_R_DIR_NOT_FOUND; -} - -static pcb_r_dir_t LOCtoLineRat_callback(const pcb_box_t * b, void *cl) -{ - pcb_rat_t *rat = (pcb_rat_t *) b; - struct lo_info *i = (struct lo_info *) cl; - - if (!PCB_FLAG_TEST(TheFlag, rat)) { - if ((rat->group1 == i->layer) - && pcb_isc_ratp_line(&rat->Point1, &i->line)) { - if (ADD_RAT_TO_LIST(rat, PCB_OBJ_LINE, &i->line, PCB_FCT_RAT, i->orig_line)) - longjmp(i->env, 1); - } - else if ((rat->group2 == i->layer) - && pcb_isc_ratp_line(&rat->Point2, &i->line)) { - if (ADD_RAT_TO_LIST(rat, PCB_OBJ_LINE, &i->line, PCB_FCT_RAT, i->orig_line)) - longjmp(i->env, 1); - } - } - return PCB_R_DIR_NOT_FOUND; -} - -/* searches all LOs that are connected to the given line on the given - * layergroup. All found connections are added to the list - * - * the notation that is used is: - * Xij means Xj at line i */ -static pcb_bool LookupLOConnectionsToLine(pcb_line_t *Line, pcb_cardinal_t LayerGroup, pcb_bool PolysTo) -{ - pcb_cardinal_t entry; - struct lo_info info; - - info.line = *Line; - info.orig_line = Line; - info.layer = LayerGroup; - EXPAND_BOUNDS(&info.line) - /* add the new rat lines */ - if (setjmp(info.env) == 0) - pcb_r_search(PCB->Data->rat_tree, &info.line.BoundingBox, NULL, LOCtoLineRat_callback, &info, NULL); - else - return pcb_true; - - /* loop over all layers of the group */ - for (entry = 0; entry < PCB->LayerGroups.grp[LayerGroup].len; entry++) { - pcb_layer_id_t layer; - - layer = PCB->LayerGroups.grp[LayerGroup].lid[entry]; - - info.layer = layer; - /* add lines */ - if (setjmp(info.env) == 0) - pcb_r_search(LAYER_PTR(layer)->line_tree, (pcb_box_t *) & info.line, NULL, LOCtoLineLine_callback, &info, NULL); - else - return pcb_true; - /* add arcs */ - if (setjmp(info.env) == 0) - pcb_r_search(LAYER_PTR(layer)->arc_tree, (pcb_box_t *) & info.line, NULL, LOCtoLineArc_callback, &info, NULL); - else - return pcb_true; - /* now check all polygons */ - if (PolysTo) { - pcb_rtree_it_t it; - pcb_box_t *b; - for(b = pcb_r_first(PCB->Data->Layer[layer].polygon_tree, &it); b != NULL; b = pcb_r_next(&it)) { - pcb_poly_t *polygon = (pcb_poly_t *)b; - if (!PCB_FLAG_TEST(TheFlag, polygon) && pcb_isc_line_poly(Line, polygon) - && ADD_POLYGON_TO_LIST(layer, polygon, PCB_OBJ_LINE, Line, PCB_FCT_COPPER, Line)) - return pcb_true; - } - pcb_r_end(&it); - } - } - - return pcb_false; -} - - -struct rat_info { - pcb_cardinal_t layer; - pcb_point_t *Point; - jmp_buf env; -}; - -static pcb_r_dir_t LOCtoRatLine_callback(const pcb_box_t * b, void *cl) -{ - pcb_line_t *line = (pcb_line_t *) b; - struct rat_info *i = (struct rat_info *) cl; - - if (!PCB_FLAG_TEST(TheFlag, line) && pcb_isc_ratp_line(i->Point, line)) { - if (ADD_LINE_TO_LIST(i->layer, line, PCB_OBJ_RAT, &i->Point, PCB_FCT_RAT, NULL)) - longjmp(i->env, 1); - } - return PCB_R_DIR_NOT_FOUND; -} - -static pcb_r_dir_t LOCtoRatArc_callback(const pcb_box_t * b, void *cl) -{ - pcb_arc_t *arc = (pcb_arc_t *) b; - struct rat_info *i = (struct rat_info *) cl; - - if (!PCB_FLAG_TEST(TheFlag, arc) && pcb_isc_ratp_arc(i->Point, arc)) { - if (ADD_ARC_TO_LIST(i->layer, arc, PCB_OBJ_RAT, &i->Point, PCB_FCT_RAT, NULL)) - longjmp(i->env, 1); - } - return PCB_R_DIR_NOT_FOUND; -} - -static pcb_r_dir_t LOCtoRatPoly_callback(const pcb_box_t * b, void *cl) -{ - pcb_poly_t *polygon = (pcb_poly_t *) b; - struct rat_info *i = (struct rat_info *) cl; - - if (!PCB_FLAG_TEST(TheFlag, polygon) && polygon->Clipped && pcb_isc_ratp_poly(i->Point, polygon)) { - if (ADD_POLYGON_TO_LIST(i->layer, polygon, PCB_OBJ_RAT, &i->Point, PCB_FCT_RAT, NULL)) - longjmp(i->env, 1); - } - return PCB_R_DIR_NOT_FOUND; -} - -/* searches all LOs that are connected to the given rat-line on the given - * layergroup. All found connections are added to the list - * - * the notation that is used is: - * Xij means Xj at line i */ -static pcb_bool LookupLOConnectionsToRatEnd(pcb_point_t *Point, pcb_cardinal_t LayerGroup) -{ - pcb_cardinal_t entry; - struct rat_info info; - - info.Point = Point; - /* loop over all layers of this group */ - for (entry = 0; entry < PCB->LayerGroups.grp[LayerGroup].len; entry++) { - pcb_layer_id_t layer; - - layer = PCB->LayerGroups.grp[LayerGroup].lid[entry]; - info.layer = layer; - if (setjmp(info.env) == 0) - r_search_pt(LAYER_PTR(layer)->arc_tree, Point, 1, NULL, LOCtoRatArc_callback, &info, NULL); - else - return pcb_true; - if (setjmp(info.env) == 0) - r_search_pt(LAYER_PTR(layer)->line_tree, Point, 1, NULL, LOCtoRatLine_callback, &info, NULL); - else - return pcb_true; - if (setjmp(info.env) == 0) - r_search_pt(LAYER_PTR(layer)->polygon_tree, Point, 1, NULL, LOCtoRatPoly_callback, &info, NULL); - } - - return pcb_false; -} - -static pcb_r_dir_t LOCtoPolyLine_callback(const pcb_box_t * b, void *cl) -{ - pcb_line_t *line = (pcb_line_t *) b; - struct lo_info *i = (struct lo_info *) cl; - - if (!PCB_FLAG_TEST(TheFlag, line) && pcb_isc_line_poly(line, &i->polygon) && !INOCN(line, &i->polygon)) { - if (ADD_LINE_TO_LIST(i->layer, line, PCB_OBJ_POLY, &i->polygon, PCB_FCT_COPPER, i->orig_polygon)) - longjmp(i->env, 1); - } - return PCB_R_DIR_NOT_FOUND; -} - -static pcb_r_dir_t LOCtoPolyArc_callback(const pcb_box_t * b, void *cl) -{ - pcb_arc_t *arc = (pcb_arc_t *) b; - struct lo_info *i = (struct lo_info *) cl; - - if (!arc->Thickness) - return 0; - if (!PCB_FLAG_TEST(TheFlag, arc) && pcb_isc_arc_poly(arc, &i->polygon) && !INOCN(arc, &i->polygon)) { - if (ADD_ARC_TO_LIST(i->layer, arc, PCB_OBJ_POLY, &i->polygon, PCB_FCT_COPPER, i->orig_polygon)) - longjmp(i->env, 1); - } - return 0; -} - -static pcb_r_dir_t LOCtoPolyRat_callback(const pcb_box_t * b, void *cl) -{ - pcb_rat_t *rat = (pcb_rat_t *) b; - struct lo_info *i = (struct lo_info *) cl; - - if (!PCB_FLAG_TEST(TheFlag, rat)) { - if (((rat->group1 == i->layer) && pcb_isc_ratp_poly(&rat->Point1, &i->polygon)) - || ((rat->group2 == i->layer) && pcb_isc_ratp_poly(&rat->Point2, &i->polygon))) { - if (ADD_RAT_TO_LIST(rat, PCB_OBJ_POLY, &i->polygon, PCB_FCT_RAT, i->orig_polygon)) - longjmp(i->env, 1); - } - } - return PCB_R_DIR_NOT_FOUND; -} - - -/* looks up LOs that are connected to the given polygon - * on the given layergroup. All found connections are added to the list */ -static pcb_bool LookupLOConnectionsToPolygon(pcb_poly_t *Polygon, pcb_cardinal_t LayerGroup) -{ - pcb_cardinal_t entry; - struct lo_info info; - - if (!Polygon->Clipped) - return pcb_false; - info.polygon = *Polygon; - info.orig_polygon = Polygon; - EXPAND_BOUNDS(&info.polygon); - info.layer = LayerGroup; - /* check rats */ - if (setjmp(info.env) == 0) - pcb_r_search(PCB->Data->rat_tree, (pcb_box_t *) & info.polygon, NULL, LOCtoPolyRat_callback, &info, NULL); - else - return pcb_true; -/* loop over all layers of the group */ - for (entry = 0; entry < PCB->LayerGroups.grp[LayerGroup].len; entry++) { - pcb_layer_id_t layer; - - layer = PCB->LayerGroups.grp[LayerGroup].lid[entry]; - - /* handle normal layers */ - /* check all polygons */ - { - pcb_rtree_it_t it; - pcb_box_t *b; - for(b = pcb_r_first(PCB->Data->Layer[layer].polygon_tree, &it); b != NULL; b = pcb_r_next(&it)) { - pcb_poly_t *polygon = (pcb_poly_t *)b; - if (!PCB_FLAG_TEST(TheFlag, polygon) - && pcb_isc_poly_poly(polygon, Polygon) - && ADD_POLYGON_TO_LIST(layer, polygon, PCB_OBJ_POLY, Polygon, PCB_FCT_COPPER, Polygon)) - return pcb_true; - } - pcb_r_end(&it); - } - - info.layer = layer; - /* check all lines */ - if (setjmp(info.env) == 0) - pcb_r_search(LAYER_PTR(layer)->line_tree, (pcb_box_t *) & info.polygon, NULL, LOCtoPolyLine_callback, &info, NULL); - else - return pcb_true; - /* check all arcs */ - if (setjmp(info.env) == 0) - pcb_r_search(LAYER_PTR(layer)->arc_tree, (pcb_box_t *) & info.polygon, NULL, LOCtoPolyArc_callback, &info, NULL); - else - return pcb_true; - } - - return pcb_false; -} Index: trunk/src/find2.c =================================================================== --- trunk/src/find2.c (revision 21905) +++ trunk/src/find2.c (nonexistent) @@ -1,357 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2018 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") - */ - -/* Follow galvanic connections through overlapping objects */ - -#include "config.h" -#include "find2.h" - - -#include "find_geo.c" -#include "find_any_isect.c" - -/* trickery: keeping vtp0 is reentrant and is cheaper than keeping lists, - at least for appending. But as long as only the last item is removed, - it's also cheap on remove! */ - -/* Do everything that needs to be done for an object found */ -static int pcb_find_found(pcb_find_t *ctx, pcb_any_obj_t *obj, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype) -{ - if (ctx->list_found) - vtp0_append(&ctx->found, obj); - - if ((ctx->flag_set != 0) || (ctx->flag_clr != 0)) { - if (ctx->flag_chg_undoable) - pcb_undo_add_obj_to_flag(obj); - if (ctx->flag_set != 0) - PCB_FLAG_SET(ctx->flag_set, obj); - if (ctx->flag_clr != 0) - PCB_FLAG_CLEAR(ctx->flag_clr, obj); - } - - ctx->nfound++; - - if ((ctx->found_cb != NULL) && (ctx->found_cb(ctx, obj, arrived_from, ctype) != 0)) { - ctx->aborted = 1; - return 1; - } - - return 0; -} - - -static int pcb_find_addobj(pcb_find_t *ctx, pcb_any_obj_t *obj, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype) -{ - PCB_DFLAG_SET(&obj->Flags, ctx->mark); - vtp0_append(&ctx->open, obj); - - if (pcb_find_found(ctx, obj, arrived_from, ctype) != 0) { - ctx->aborted = 1; - return 1; - } - return 0; -} - -static void find_int_conn(pcb_find_t *ctx, pcb_any_obj_t *from_) -{ - void *from = from_; /* for warningless comparison */ - pcb_subc_t *s; - int ic; - - s = pcb_obj_parent_subc(from_); - if (s == NULL) - return; - - ic = from_->intconn; - - PCB_PADSTACK_LOOP(s->data); - { - if ((padstack != from) && (padstack->term != NULL) && (padstack->intconn == ic) && (!(PCB_DFLAG_TEST(&(padstack->Flags), ctx->mark)))) - if (pcb_find_addobj(ctx, (pcb_any_obj_t *)padstack, from_, PCB_FCT_INTCONN) != 0) - return; - } - PCB_END_LOOP; - - PCB_LINE_COPPER_LOOP(s->data); - { - if ((line != from) && (line->term != NULL) && (line->intconn == ic) && (!(PCB_DFLAG_TEST(&(line->Flags), ctx->mark)))) - if (pcb_find_addobj(ctx, (pcb_any_obj_t *)line, from_, PCB_FCT_INTCONN) != 0) - return; - } - PCB_ENDALL_LOOP; - - PCB_ARC_COPPER_LOOP(s->data); - { - if ((arc != from) && (arc->term != NULL) && (arc->intconn == ic) && (!(PCB_DFLAG_TEST(&(arc->Flags), ctx->mark)))) - if (pcb_find_addobj(ctx, (pcb_any_obj_t *)arc, from_, PCB_FCT_INTCONN) != 0) - return; - } - PCB_ENDALL_LOOP; - - PCB_POLY_COPPER_LOOP(s->data); - { - if ((polygon != from) && (polygon->term != NULL) && (polygon->intconn == ic) && (!(PCB_DFLAG_TEST(&(polygon->Flags), ctx->mark)))) - if (pcb_find_addobj(ctx, (pcb_any_obj_t *)polygon, from_, PCB_FCT_INTCONN) != 0) - return; - } - PCB_ENDALL_LOOP; - -TODO("find: no find through text yet") -#if 0 - PCB_TEXT_COPPER_LOOP(s->data); - { - if ((text != from) && (text->term != NULL) && (text->intconn == ic) && (!(PCB_DFLAG_TEST(&(text->Flags), ctx->mark)))) - if (pcb_find_addobj(ctx, (pcb_any_obj_t *)text, from_, PCB_FCT_INTCONN) != 0) - return; - } - PCB_ENDALL_LOOP; -#endif -} - -/* return whether a and b are in the same internal-no-connection group */ -static pcb_bool int_noconn(pcb_any_obj_t *a, pcb_any_obj_t *b) -{ - pcb_subc_t *pa, *pb; - - /* cheap test: they need to have valid and matching intnoconn */ - if ((a->intnoconn == 0) || (a->intnoconn != b->intnoconn)) - return pcb_false; - - /* expensive tests: they need to be in the same subc */ - pa = pcb_obj_parent_subc(a); - if (pa == NULL) - return pcb_false; - - pb = pcb_obj_parent_subc(b); - - return (pa == pb); -} - -#define INOCONN(a,b) int_noconn((pcb_any_obj_t *)a, (pcb_any_obj_t *)b) - -#define PCB_FIND_CHECK(ctx, curr, obj, ctype, retstmt) \ - do { \ - pcb_any_obj_t *__obj__ = (pcb_any_obj_t *)obj; \ - if (!(PCB_DFLAG_TEST(&(__obj__->Flags), ctx->mark))) { \ - if (!INOCONN(curr, obj) && (pcb_intersect_obj_obj(curr, __obj__))) {\ - if (pcb_find_addobj(ctx, __obj__, curr, ctype) != 0) { retstmt; } \ - if ((__obj__->term != NULL) && (!ctx->ignore_intconn) && (__obj__->intconn > 0)) \ - find_int_conn(ctx, __obj__); \ - } \ - } \ - } while(0) - -void pcb_find_on_layer(pcb_find_t *ctx, pcb_layer_t *l, pcb_any_obj_t *curr, pcb_rtree_box_t *sb, pcb_found_conn_type_t ctype) -{ - pcb_rtree_it_t it; - pcb_box_t *n; - - if (l->line_tree != NULL) { - for(n = pcb_rtree_first(&it, l->line_tree, sb); n != NULL; n = pcb_rtree_next(&it)) - PCB_FIND_CHECK(ctx, curr, n, ctype, return); - pcb_r_end(&it); - } - - if (l->arc_tree != NULL) { - for(n = pcb_rtree_first(&it, l->arc_tree, sb); n != NULL; n = pcb_rtree_next(&it)) - PCB_FIND_CHECK(ctx, curr, n, ctype, return); - pcb_r_end(&it); - } - - if (l->polygon_tree != NULL) { - for(n = pcb_rtree_first(&it, l->polygon_tree, sb); n != NULL; n = pcb_rtree_next(&it)) - PCB_FIND_CHECK(ctx, curr, n, ctype, return); - pcb_r_end(&it); - } - - if (l->text_tree != NULL) { - for(n = pcb_rtree_first(&it, l->text_tree, sb); n != NULL; n = pcb_rtree_next(&it)) - PCB_FIND_CHECK(ctx, curr, n, ctype, return); - pcb_r_end(&it); - } -} - -void pcb_find_on_layergrp(pcb_find_t *ctx, pcb_layergrp_t *g, pcb_any_obj_t *curr, pcb_rtree_box_t *sb, pcb_found_conn_type_t ctype) -{ - int n; - if (g == NULL) - return; - for(n = 0; n < g->len; n++) - pcb_find_on_layer(ctx, &ctx->data->Layer[g->lid[n]], curr, sb, ctype); -} - -static void pcb_find_rat(pcb_find_t *ctx, pcb_rat_t *rat) -{ - pcb_rtree_box_t sb; - - sb.x1 = rat->Point1.X; sb.x2 = rat->Point1.X+1; - sb.y1 = rat->Point1.Y; sb.y2 = rat->Point1.Y+1; - pcb_find_on_layergrp(ctx, pcb_get_layergrp(ctx->pcb, rat->group1), (pcb_any_obj_t *)rat, &sb, PCB_FCT_RAT); - - sb.x1 = rat->Point2.X; sb.x2 = rat->Point2.X+1; - sb.y1 = rat->Point2.Y; sb.y2 = rat->Point2.Y+1; - pcb_find_on_layergrp(ctx, pcb_get_layergrp(ctx->pcb, rat->group2), (pcb_any_obj_t *)rat, &sb, PCB_FCT_RAT); -} - -static unsigned long pcb_find_exec(pcb_find_t *ctx) -{ - pcb_any_obj_t *curr; - pcb_found_conn_type_t ctype; - - if ((ctx->start_layergrp == NULL) && (ctx->open.used > 0) && (ctx->pcb != NULL)) { - curr = ctx->open.array[0]; - if ((curr != NULL) && (curr->parent_type == PCB_PARENT_LAYER)) { - pcb_layergrp_id_t gid = pcb_layer_get_group_(curr->parent.layer); - ctx->start_layergrp = pcb_get_layergrp(ctx->pcb, gid); - if (!ctx->allow_noncopper) { - TODO("find.c: implement this; special case: starting layer object on non-copper can still jump on padstack!"); - } - } - } - - while((ctx->open.used > 0) && (!ctx->aborted)) { - /* pop the last object, without reallocating to smaller, mark it found */ - ctx->open.used--; - curr = ctx->open.array[ctx->open.used]; - ctype = curr->type == PCB_OBJ_RAT ? PCB_FCT_RAT : PCB_FCT_COPPER; - - { /* search unmkared connections: iterative approach */ - pcb_rtree_it_t it; - pcb_box_t *n; - pcb_rtree_box_t *sb = (pcb_rtree_box_t *)&curr->bbox_naked; - - if (PCB->Data->padstack_tree != NULL) { - for(n = pcb_rtree_first(&it, PCB->Data->padstack_tree, sb); n != NULL; n = pcb_rtree_next(&it)) - PCB_FIND_CHECK(ctx, curr, n, ctype, return ctx->nfound); - pcb_r_end(&it); - } - - if ((ctx->consider_rats) && (PCB->Data->rat_tree != NULL)) { - if (PCB->Data->padstack_tree != NULL) { - for(n = pcb_rtree_first(&it, PCB->Data->rat_tree, sb); n != NULL; n = pcb_rtree_next(&it)) - PCB_FIND_CHECK(ctx, curr, n, PCB_FCT_RAT, return ctx->nfound); - pcb_r_end(&it); - } - } - - if (curr->type == PCB_OBJ_PSTK) { - int li; - pcb_layer_t *l; - if ((!ctx->stay_layergrp) || (ctx->start_layergrp == NULL)) { - for(li = 0, l = ctx->data->Layer; li < ctx->data->LayerN; li++,l++) { - if (!ctx->allow_noncopper) { - TODO("find.c: implement this"); - } - if (pcb_pstk_shape_at_(ctx->pcb, (pcb_pstk_t *)curr, l, 0)) - pcb_find_on_layer(ctx, l, curr, sb, ctype); - } - } - else { - for(li = 0; li < ctx->start_layergrp->len; li++) { - l = pcb_get_layer(ctx->data, ctx->start_layergrp->lid[li]); - if (l != NULL) - pcb_find_on_layer(ctx, l, curr, sb, ctype); - } - } - } - else if (curr->type == PCB_OBJ_RAT) { - pcb_find_rat(ctx, (pcb_rat_t *)curr); - } - else { - /* layer objects need to be checked against same layer objects only */ - assert(curr->parent_type == PCB_PARENT_LAYER); - pcb_find_on_layer(ctx, curr->parent.layer, curr, sb, ctype); - } - } - } - - if (ctx->flag_chg_undoable) - pcb_undo_inc_serial(); - - return ctx->nfound; -} - -static int pcb_find_init_(pcb_find_t *ctx, pcb_data_t *data) -{ - if (ctx->in_use) - return -1; - ctx->in_use = 1; - ctx->aborted = 0; - ctx->mark = pcb_dynflag_alloc("pcb_find_from_obj"); - ctx->data = data; - ctx->nfound = 0; - ctx->start_layergrp = NULL; - ctx->pcb = pcb_data_get_top(data); - - if (ctx->list_found) - vtp0_init(&ctx->found); - vtp0_init(&ctx->open); - return 0; -} - -unsigned long pcb_find_from_obj(pcb_find_t *ctx, pcb_data_t *data, pcb_any_obj_t *from) -{ - if (pcb_find_init_(ctx, data) < 0) - return -1; - - pcb_data_dynflag_clear(data, ctx->mark); - pcb_find_addobj(ctx, from, NULL, PCB_FCT_START); /* add the starting object with no 'arrived_from' */ - return pcb_find_exec(ctx); -} - - -unsigned long pcb_find_from_xy(pcb_find_t *ctx, pcb_data_t *data, pcb_coord_t x, pcb_coord_t y) -{ - void *ptr1, *ptr2, *ptr3; - pcb_any_obj_t *obj; - int type; - - type = pcb_search_obj_by_location(PCB_LOOKUP_FIRST, &ptr1, &ptr2, &ptr3, x, y, PCB_SLOP * pcb_pixel_slop); - if (type == PCB_OBJ_VOID) - type = pcb_search_obj_by_location(PCB_LOOKUP_MORE, &ptr1, &ptr2, &ptr3, x, y, PCB_SLOP * pcb_pixel_slop); - - if (type == PCB_OBJ_VOID) - return -1; - - obj = ptr2; - if ((obj->parent_type == PCB_PARENT_LAYER) && ((pcb_layer_flags_(obj->parent.layer) & PCB_LYT_COPPER) == 0)) - return -1; /* non-conductive object */ - - return pcb_find_from_obj(ctx, data, obj); -} - - -void pcb_find_free(pcb_find_t *ctx) -{ - if (!ctx->in_use) - return; - if (ctx->list_found) - vtp0_uninit(&ctx->found); - vtp0_uninit(&ctx->open); - pcb_dynflag_free(ctx->mark); - ctx->in_use = 0; -} - Index: trunk/src/find2.h =================================================================== --- trunk/src/find2.h (revision 21905) +++ trunk/src/find2.h (nonexistent) @@ -1,101 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2018 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") - */ - -/* Follow galvanic connections through overlapping objects */ - -#ifndef PCB_FIND2_H -#define PCB_FIND2_H - -#include -#include "flag.h" - -typedef enum { - PCB_FCT_COPPER = 1, /* copper connection */ - PCB_FCT_INTCONN = 2, /* subc internal connection, using the intconn attrib */ - PCB_FCT_RAT = 4, /* connected between a rat line and anything else */ - PCB_FCT_START = 8 /* starting object of a query */ -} pcb_found_conn_type_t; - -typedef struct pcb_find_s pcb_find_t; -struct pcb_find_s { - /* public config - all-zero uses the original method, except for flag set */ - unsigned stay_layergrp:1; /* do not leave the layer (no padstack hop) */ - unsigned allow_noncopper:1; /* also run on non-copper objects */ - unsigned list_found:1; /* allow adding objects in the ->found vector */ - unsigned ignore_intconn:1; /* do not jump terminals on subc intconn */ - unsigned consider_rats:1; /* don't ignore rat lines, don't consider physical objects only */ - unsigned flag_chg_undoable:1; /* when set, and flag_set or flag_clr is non-zero, put all found objects on the flag-undo before the flag change */ - unsigned long flag_set; /* when non-zero, set the static flag bits on objects found */ - unsigned long flag_clr; /* when non-zero, remove the static flag bits on objects found */ - - /* if non-NULL, call after an object is found; if returns non-zero, - set ->aborted and stop the search. When search started from an object, - it is called for the starting object as well. All object data and ctx - fields are updated for new_obj before the call. arrived_from is - the previous object (that already triggered a callback) from which - new_obj was first found; can be NULL for the starting object. ctype - describes the relation between arrived_from and new_obj. */ - int (*found_cb)(pcb_find_t *ctx, pcb_any_obj_t *new_obj, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype); - - /* public state/result */ - vtp0_t found; /* objects found, when list_found is 1 - of (pcb_any_obj_t *) */ - void *user_data; /* filled in by caller, not read or modified by find code */ - - /* private */ - vtp0_t open; /* objects already found but need checking for conns of (pcb_any_obj_t *) */ - pcb_data_t *data; - pcb_board_t *pcb; - pcb_layergrp_t *start_layergrp; - pcb_dynf_t mark; - unsigned long nfound; - unsigned in_use:1; - unsigned aborted:1; -}; - - -unsigned long pcb_find_from_obj(pcb_find_t *ctx, pcb_data_t *data, pcb_any_obj_t *from); -unsigned long pcb_find_from_xy(pcb_find_t *ctx, pcb_data_t *data, pcb_coord_t x, pcb_coord_t y); - -void pcb_find_free(pcb_find_t *ctx); - -/* High level intersection function: returns if a and b intersect (overlap) */ -pcb_bool pcb_intersect_obj_obj(pcb_any_obj_t *a, pcb_any_obj_t *b); - -/* Low level intersection functions: */ -pcb_bool pcb_isc_line_line(pcb_line_t *Line1, pcb_line_t *Line2); -pcb_bool pcb_isc_line_arc(pcb_line_t *Line, pcb_arc_t *Arc); -pcb_bool pcb_isc_arc_poly(pcb_arc_t *Arc, pcb_poly_t *Polygon); -pcb_bool pcb_isc_arc_polyarea(pcb_arc_t *Arc, pcb_polyarea_t *pa); -pcb_bool pcb_isc_line_poly(pcb_line_t *Line, pcb_poly_t *Polygon); -pcb_bool pcb_isc_poly_poly(pcb_poly_t *P1, pcb_poly_t *P2); -pcb_bool_t pcb_isc_pstk_line(pcb_pstk_t *ps, pcb_line_t *line); - -#define PCB_LOOKUP_FIRST \ - (PCB_OBJ_PSTK | PCB_OBJ_SUBC_PART) -#define PCB_LOOKUP_MORE \ - (PCB_OBJ_LINE | PCB_OBJ_RAT | PCB_OBJ_POLY | PCB_OBJ_ARC | PCB_OBJ_SUBC_PART) - -#endif Index: trunk/src/Makefile.dep =================================================================== --- trunk/src/Makefile.dep (revision 21905) +++ trunk/src/Makefile.dep (revision 21906) @@ -212,7 +212,7 @@ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h macro.h \ ../src_plugins/autoroute/autoroute.h board.h vtroutestyle.h library.h \ - rats_patch.h board.h box.h draw.h error.h find.h find2.h heap.h rtree.h \ + rats_patch.h board.h box.h draw.h error.h find.h heap.h rtree.h \ ../src_plugins/autoroute/mtspace.h ../src_plugins/autoroute/vector.h \ polygon.h rats.h netlist.h route_style.h remove.h obj_pinvia_therm.h \ undo.h ../src_3rd/libuundo/uundo.h undo_old.h pcb-printf.h layer.h \ @@ -350,7 +350,7 @@ ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h error.h event.h \ ../src_plugins/diag/integrity.h hid.h hid_attrib.h hid_dad.h \ compat_misc.h hid_attrib.h search.h rats.h netlist.h route_style.h \ - macro.h funchash_core.h funchash.h funchash_core_list.h find.h find2.h \ + macro.h funchash_core.h funchash.h funchash_core_list.h find.h \ dolists.h ../src_plugins/diag/diag_conf_fields.h ../src_plugins/diag/diag_conf.o: ../src_plugins/diag/diag_conf.c \ ../config.h conf.h global_typedefs.h pcb_bool.h unit.h pcb-printf.h \ @@ -577,7 +577,7 @@ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h remove.h move.h \ draw.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h flag_str.h find.h \ - find2.h layer.h pcb-printf.h compat_misc.h plugins.h \ + layer.h pcb-printf.h compat_misc.h plugins.h \ ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h hid_flags.h actions.h \ @@ -686,7 +686,7 @@ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ vtpadstack_t.h conf_core.h conf.h pcb-printf.h \ - ../src_3rd/liblihata/lihata.h list_conf.h find.h find2.h event.h \ + ../src_3rd/liblihata/lihata.h list_conf.h find.h event.h \ plugins.h ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h layer_vis.h \ @@ -1022,7 +1022,7 @@ draw.h plugins.h ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h plug_io.h find.h \ - find2.h macro.h obj_subc_parent.h undo.h ../src_3rd/libuundo/uundo.h \ + macro.h obj_subc_parent.h undo.h ../src_3rd/libuundo/uundo.h \ undo_old.h funchash_core.h funchash.h funchash_core_list.h search.h \ rats.h netlist.h route_style.h hid_init.h hid_attrib.h dolists.h ../src_plugins/export_openems/export_openems.o: \ @@ -1995,7 +1995,7 @@ ../src_3rd/genrtree/genrtree_api.h rtree2_compat.h ht_subc.h \ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ - vtpadstack_t.h find.h find2.h rats.h netlist.h library.h route_style.h \ + vtpadstack_t.h find.h rats.h netlist.h library.h route_style.h \ vtroutestyle.h select.h operation.h undo.h ../src_3rd/libuundo/uundo.h \ undo_old.h remove.h crosshair.h draw.h event.h hid.h actions.h \ ../src_plugins/hid_lesstif/lesstif.h hid_cfg_input.h hid_cfg.h \ @@ -3340,7 +3340,7 @@ pcb-printf.h ../src_3rd/liblihata/lihata.h list_conf.h \ ../src_plugins/lib_compat_help/pstk_help.c \ ../src_plugins/lib_compat_help/pstk_help.h search.h rats.h netlist.h \ - route_style.h remove.h find.h find2.h \ + route_style.h remove.h find.h \ ../src_plugins/lib_compat_help/subc_help.c \ ../src_plugins/lib_compat_help/subc_help.h obj_subc.h \ ../src_plugins/lib_compat_help/elem_rot.c \ @@ -3438,7 +3438,7 @@ ../src_3rd/genht/htip.h ../src_3rd/genht/ht.h box.h math_helper.h move.h \ misc_util.h ../src_3rd/genvector/gds_char.h library.h search.h rats.h \ netlist.h library.h route_style.h vtroutestyle.h layer.h layer_grp.h \ - find.h find2.h ../src_3rd/genvector/vtp0.h board.h rats_patch.h board.h \ + find.h ../src_3rd/genvector/vtp0.h board.h rats_patch.h board.h \ obj_subc.h ../src_3rd/libminuid/libminuid.h ../src_3rd/genht/htsp.h \ rtree.h ../src_3rd/genrtree/genrtree_api.h rtree2_compat.h \ obj_subc_parent.h data.h crosshair.h vtonpoint.h hid.h \ @@ -3729,7 +3729,7 @@ ../src_3rd/genrtree/genrtree_api.h rtree2_compat.h ht_subc.h \ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h error.h \ - macro.h find.h find2.h rats.h netlist.h route_style.h remove.h search.h \ + macro.h find.h rats.h netlist.h route_style.h remove.h search.h \ rats.h select.h operation.h undo.h ../src_3rd/libuundo/uundo.h \ undo_old.h actions.h compat_nls.h \ ../src_plugins/lib_gtk_common/util_str.h \ @@ -4666,7 +4666,7 @@ ../src_3rd/genrtree/genrtree_api.h rtree2_compat.h ht_subc.h \ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ - vtpadstack_t.h find.h find2.h netlist.h route_style.h pcb-printf.h \ + vtpadstack_t.h find.h netlist.h route_style.h pcb-printf.h \ plugins.h ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h @@ -4847,7 +4847,7 @@ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ vtpadstack_t.h draw.h error.h plug_io.h library.h conf.h pcb-printf.h \ - ../src_3rd/liblihata/lihata.h list_conf.h find.h find2.h polygon.h \ + ../src_3rd/liblihata/lihata.h list_conf.h find.h polygon.h \ search.h rats.h netlist.h route_style.h vtroutestyle.h undo.h \ ../src_3rd/libuundo/uundo.h undo_old.h plugins.h \ ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ @@ -4908,7 +4908,7 @@ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ ../src_3rd/genvector/vtp0.h vtpadstack.h obj_pstk_shape.h polygon.h \ vtpadstack_t.h macro.h remove.h hid.h error.h rtree.h polygon.h \ - polyarea.h flag_str.h find.h find2.h draw.h undo.h \ + polyarea.h flag_str.h find.h draw.h undo.h \ ../src_3rd/libuundo/uundo.h undo_old.h plugins.h \ ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ @@ -5031,7 +5031,7 @@ ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h actions.h misc_util.h \ compat_misc.h obj_pstk_inlines.h data.h thermal.h funchash_core.h \ funchash.h funchash_core_list.h search.h rats.h netlist.h route_style.h \ - find.h find2.h dolists.h + find.h dolists.h ../src_plugins/query/basic_fnc.o: ../src_plugins/query/basic_fnc.c \ ../config.h data.h globalconst.h global_typedefs.h pcb_bool.h unit.h \ layer.h attrib.h color.h ../src_3rd/genvector/genvector_impl.h \ @@ -5279,7 +5279,7 @@ vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h data_it.h data.h \ ../src_plugins/report/drill.h error.h search.h rats.h netlist.h \ route_style.h rats.h rtree.h flag_str.h macro.h undo.h \ - ../src_3rd/libuundo/uundo.h undo_old.h find.h find2.h draw.h \ + ../src_3rd/libuundo/uundo.h undo_old.h find.h draw.h \ pcb-printf.h plugins.h ../src_3rd/puplug/puplug.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/os_dep.h \ ../src_3rd/puplug/config.h ../src_3rd/puplug/libs.h \ @@ -5375,7 +5375,7 @@ vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h data_it.h data.h \ error.h search.h rats.h netlist.h route_style.h tool.h rats.h rtree.h \ flag_str.h macro.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h find.h \ - find2.h draw.h draw_wireframe.h pcb-printf.h plugins.h \ + draw.h draw_wireframe.h pcb-printf.h plugins.h \ ../src_3rd/puplug/puplug.h ../src_3rd/puplug/libs.h \ ../src_3rd/puplug/os_dep.h ../src_3rd/puplug/config.h \ ../src_3rd/puplug/libs.h ../src_3rd/puplug/error.h actions.h \ @@ -6090,7 +6090,7 @@ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h \ draw_wireframe.h search.h rats.h netlist.h route_style.h actions.h \ - hid_inlines.h compat_misc.h compat_nls.h find.h find2.h undo.h \ + hid_inlines.h compat_misc.h compat_nls.h find.h undo.h \ ../src_3rd/libuundo/uundo.h undo_old.h event.h macro.h grid.h \ stub_stroke.h obj_line_draw.h obj_arc_draw.h obj_text_draw.h \ obj_pstk_draw.h obj_arc_ui.h obj_subc_parent.h tool.h @@ -6210,7 +6210,7 @@ ../src_3rd/genrtree/genrtree_api.h rtree2_compat.h ht_subc.h \ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h plug_io.h \ - plug_import.h remove.h draw.h find.h find2.h search.h rats.h netlist.h \ + plug_import.h remove.h draw.h find.h search.h rats.h netlist.h \ route_style.h actions.h compat_misc.h compat_nls.h hid_init.h \ layer_vis.h safe_fs.h tool.h find.o: find.c ../config.h math_helper.h conf_core.h conf.h \ @@ -6232,12 +6232,12 @@ ../src_3rd/genrtree/genrtree_api.h rtree2_compat.h ht_subc.h \ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h find.h \ - find2.h search.h rats.h netlist.h library.h route_style.h vtroutestyle.h \ + search.h rats.h netlist.h library.h route_style.h vtroutestyle.h \ undo.h ../src_3rd/libuundo/uundo.h undo_old.h plug_io.h actions.h \ compat_misc.h event.h layer_vis.h obj_text_draw.h obj_subc_parent.h \ - find2.c find_geo.c macro.h obj_arc_ui.h obj_pstk_inlines.h board.h \ - rats_patch.h thermal.h find_any_isect.c find_lookup.c compat_nls.h \ - find_intconn.c find_misc.c change.h obj_arc_draw.h obj_rat_draw.h \ + macro.h obj_arc_ui.h obj_pstk_inlines.h board.h \ + rats_patch.h thermal.h find_any_isect.c compat_nls.h \ + change.h obj_arc_draw.h obj_rat_draw.h \ obj_line_draw.h obj_poly_draw.h obj_pstk_draw.h flag.o: flag.c ../config.h flag.h globalconst.h operation.h \ global_typedefs.h pcb_bool.h unit.h @@ -6316,7 +6316,7 @@ vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h tool.h grid.h \ undo.h ../src_3rd/libuundo/uundo.h undo_old.h funchash_core.h funchash.h \ funchash_core_list.h change.h draw.h search.h rats.h netlist.h \ - route_style.h find.h find2.h stub_stroke.h actions.h hid_init.h \ + route_style.h find.h stub_stroke.h actions.h hid_init.h \ compat_nls.h compat_misc.h event.h layer_ui.h layer_vis.h hid_attrib.h \ operation.h obj_subc_op.h heap.o: heap.c ../config.h heap.h @@ -6748,7 +6748,7 @@ error.h plug_io.h conf.h pcb-printf.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/dom.h ../src_3rd/liblihata/lihata.h \ ../src_3rd/liblihata/parser.h ../src_3rd/genht/htsp.h \ - ../src_3rd/genvector/vtp0.h list_conf.h find.h find2.h rats.h netlist.h \ + ../src_3rd/genvector/vtp0.h list_conf.h find.h rats.h netlist.h \ route_style.h actions.h hid.h ../src_3rd/libfungw/fungw.h \ ../src_3rd/genht/htpp.h compat_misc.h event.h data.h crosshair.h \ vtonpoint.h route.h buffer.h obj_rat_list.h obj_rat.h obj_subc_list.h \ @@ -6881,7 +6881,7 @@ obj_subc.h ../src_3rd/libminuid/libminuid.h rtree.h \ ../src_3rd/genrtree/genrtree_api.h rtree2_compat.h ht_subc.h \ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ - vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h find.h find2.h \ + vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h find.h \ macro.h obj_line_list.o: obj_line_list.c obj_line_list.h obj_line.h \ ../src_3rd/genlist/gendlist.h obj_common.h flag.h globalconst.h \ @@ -7390,7 +7390,7 @@ ../src_3rd/genrtree/genrtree_api.h rtree2_compat.h ht_subc.h \ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h find.h \ - find2.h rats.h netlist.h route_style.h search.h undo.h \ + rats.h netlist.h route_style.h search.h undo.h \ ../src_3rd/libuundo/uundo.h undo_old.h stub_mincut.h compat_misc.h \ compat_nls.h macro.h obj_rat_draw.h obj_term.h obj_subc_parent.h \ obj_pstk_inlines.h thermal.h brave.h @@ -7414,7 +7414,7 @@ ../src_3rd/genrtree/genrtree_api.h rtree2_compat.h ht_subc.h \ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h undo.h \ - ../src_3rd/libuundo/uundo.h undo_old.h find.h find2.h remove.h \ + ../src_3rd/libuundo/uundo.h undo_old.h find.h remove.h \ funchash_core.h funchash.h funchash_core_list.h compat_nls.h actions.h \ rats.h netlist.h route_style.h draw.h obj_rat_draw.h brave.h rats_patch.o: rats_patch.c rats_patch.h board.h ../config.h \ @@ -7519,7 +7519,7 @@ obj_subc.h ../src_3rd/libminuid/libminuid.h rtree.h \ ../src_3rd/genrtree/genrtree_api.h rtree2_compat.h ht_subc.h \ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ - vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h find.h find2.h \ + vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h find.h \ undo.h ../src_3rd/libuundo/uundo.h undo_old.h obj_line_draw.h draw.h \ obj_arc_draw.h obj_line_op.h operation.h draw_wireframe.h route_style.o: route_style.c ../config.h pcb-printf.h \ @@ -7573,7 +7573,7 @@ obj_subc.h ../src_3rd/libminuid/libminuid.h rtree.h \ ../src_3rd/genrtree/genrtree_api.h rtree2_compat.h ht_subc.h \ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ - vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h find.h find2.h \ + vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h find.h \ search.h rats.h netlist.h route_style.h obj_subc_parent.h \ obj_pstk_inlines.h thermal.h select.o: select.c ../config.h conf_core.h conf.h global_typedefs.h \ @@ -7597,7 +7597,7 @@ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h data_it.h draw.h \ search.h rats.h netlist.h route_style.h select.h operation.h undo.h \ - ../src_3rd/libuundo/uundo.h undo_old.h find.h find2.h compat_misc.h \ + ../src_3rd/libuundo/uundo.h undo_old.h find.h compat_misc.h \ compat_nls.h obj_arc_draw.h obj_line_draw.h obj_poly_draw.h \ obj_text_draw.h obj_rat_draw.h obj_pstk_draw.h \ ../src_3rd/genregex/regex_sei.h ../src_3rd/genregex/regex_templ.h \ @@ -7683,7 +7683,7 @@ ../src_3rd/genrtree/genrtree_api.h rtree2_compat.h ht_subc.h \ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h event.h \ - find.h find2.h grid.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ + find.h grid.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h \ actions.h tool_arc.h tool_arrow.h tool_buffer.h tool_copy.h \ tool_insert.h tool_line.h tool_lock.h tool_move.h tool_poly.h \ tool_polyhole.h tool_rectangle.h tool_remove.h tool_rotate.h tool_text.h \ @@ -7804,7 +7804,7 @@ ../src_3rd/genrtree/genrtree_api.h rtree2_compat.h ht_subc.h \ ../src_3rd/genht/ht.h ../src_3rd/genht/hash.h obj_pstk_list.h obj_pstk.h \ vtpadstack.h obj_pstk_shape.h polygon.h vtpadstack_t.h draw.h \ - draw_wireframe.h find.h find2.h rats.h netlist.h route_style.h search.h \ + draw_wireframe.h find.h rats.h netlist.h route_style.h search.h \ tool.h undo.h ../src_3rd/libuundo/uundo.h undo_old.h obj_line_draw.h \ obj_pstk_draw.h obj_rat_draw.h \ ../src_plugins/lib_compat_help/pstk_compat.h obj_pstk.h Index: trunk/src/find.c =================================================================== --- trunk/src/find.c (revision 21905) +++ trunk/src/find.c (revision 21906) @@ -1,10 +1,8 @@ /* - * * COPYRIGHT * * pcb-rnd, interactive printed circuit board design - * (this file is based on PCB, interactive printed circuit board design) - * Copyright (C) 1994,1995,1996, 2005 Thomas Nau + * Copyright (C) 2018 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 @@ -18,134 +16,345 @@ * * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * 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") - * */ +/* Follow galvanic connections through overlapping objects */ -/* - * short description: - * - lists for padstacks, lines, arcs, pads and for polygons are created. - * Every object that has to be checked is added to its list. - * Coarse searching is accomplished with the data rtrees. - * - there's no 'speed-up' mechanism for polygons because they are not used - * as often as other objects - * - the maximum distance between line and pin ... would depend on the angle - * between them. To speed up computation the limit is set to one half - * of the thickness of the objects (cause of square pins). - * - * PS: means padstack - * LO: all non PS objects (layer objects like lines, arcs, polygons, texts) - * - * 1. first, the LO or PS at the given coordinates is looked up - * 2. all LO connections to that PS are looked up next - * 3. lookup of all LOs connected to LOs from (2). - * This step is repeated until no more new connections are found. - * 4. lookup all PSs connected to the LOs from (2) and (3) - * 5. start again with (1) for all new PSs from (4) - * - */ - -/* routines to find connections between objects */ #include "config.h" - -#include -#include -#include -#include - -#include "math_helper.h" -#include "conf_core.h" -#include "data.h" -#include "draw.h" -#include "error.h" #include "find.h" -#include "rtree.h" -#include "polygon.h" -#include "search.h" #include "undo.h" -#include "rats.h" -#include "plug_io.h" -#include "actions.h" -#include "misc_util.h" -#include "compat_misc.h" -#include "layer.h" -#include "event.h" -#include "layer_vis.h" - -#include "obj_text_draw.h" -#include "obj_pstk.h" -#include "obj_subc.h" #include "obj_subc_parent.h" -#undef DEBUG +pcb_coord_t Bloat = 0; -#define LINELIST_ENTRY(L,I) \ - (((pcb_line_t **)LineList[(L)].Data)[(I)]) +#include "find_geo.c" +#include "find_any_isect.c" -#define ARCLIST_ENTRY(L,I) \ - (((pcb_arc_t **)ArcList[(L)].Data)[(I)]) +/* trickery: keeping vtp0 is reentrant and is cheaper than keeping lists, + at least for appending. But as long as only the last item is removed, + it's also cheap on remove! */ -#define RATLIST_ENTRY(I) \ - (((pcb_rat_t **)RatList.Data)[(I)]) +/* Do everything that needs to be done for an object found */ +static int pcb_find_found(pcb_find_t *ctx, pcb_any_obj_t *obj, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype) +{ + if (ctx->list_found) + vtp0_append(&ctx->found, obj); -#define POLYGONLIST_ENTRY(L,I) \ - (((pcb_poly_t **)PolygonList[(L)].Data)[(I)]) + if ((ctx->flag_set != 0) || (ctx->flag_clr != 0)) { + if (ctx->flag_chg_undoable) + pcb_undo_add_obj_to_flag(obj); + if (ctx->flag_set != 0) + PCB_FLAG_SET(ctx->flag_set, obj); + if (ctx->flag_clr != 0) + PCB_FLAG_CLEAR(ctx->flag_clr, obj); + } -#define PADSTACKLIST_ENTRY(I) \ - (((pcb_pstk_t **)PadstackList.Data)[(I)]) + ctx->nfound++; -/* --------------------------------------------------------------------------- - * the two 'dummy' structs for PVs and Pads are necessary for creating - * connection lists which include the subcircuit's name - */ -typedef struct { - void **Data; /* pointer to index data */ - pcb_cardinal_t Location, /* currently used position */ - DrawLocation, Number, /* number of objects in list */ - Size; -} ListType, *ListTypePtr; + if ((ctx->found_cb != NULL) && (ctx->found_cb(ctx, obj, arrived_from, ctype) != 0)) { + ctx->aborted = 1; + return 1; + } -pcb_coord_t Bloat = 0; -int TheFlag = PCB_FLAG_FOUND; -static int OldFlag = PCB_FLAG_FOUND; + return 0; +} -/* on DRC hit: the two offending objects */ -static void *pcb_found_obj1, *pcb_found_obj2; -#define make_callback(current_type, current_ptr, from_type, from_ptr, type) +static int pcb_find_addobj(pcb_find_t *ctx, pcb_any_obj_t *obj, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype) +{ + PCB_DFLAG_SET(&obj->Flags, ctx->mark); + vtp0_append(&ctx->open, obj); -static pcb_bool User = pcb_false; /* user action causing this */ -static pcb_bool drc = pcb_false; /* whether to stop if finding something not found */ -static pcb_cardinal_t TotalPs; -static ListType LineList[PCB_MAX_LAYER+2], /* list of objects to */ - PolygonList[PCB_MAX_LAYER+2], ArcList[PCB_MAX_LAYER+2], - RatList, PadstackList; + if (pcb_find_found(ctx, obj, arrived_from, ctype) != 0) { + ctx->aborted = 1; + return 1; + } + return 0; +} -static pcb_bool LookupLOConnectionsToPSList(pcb_bool); -static pcb_bool LookupLOConnectionsToLOList(pcb_bool); -static pcb_bool LookupLOConnectionsToLine(pcb_line_t *, pcb_cardinal_t, pcb_bool); -static pcb_bool LookupLOConnectionsToPolygon(pcb_poly_t *, pcb_cardinal_t); -static pcb_bool LookupLOConnectionsToArc(pcb_arc_t *, pcb_cardinal_t); -static pcb_bool LookupLOConnectionsToRatEnd(pcb_point_t *, pcb_cardinal_t); -static pcb_bool pcb_isc_ratp_line(pcb_point_t *, pcb_line_t *); -static pcb_bool pcb_isc_ratp_poly(pcb_point_t *Point, pcb_poly_t *polygon); -static pcb_bool pcb_isc_ratp_arc(pcb_point_t *Point, pcb_arc_t *arc); -static pcb_bool pcb_isc_arc_arc(pcb_arc_t *, pcb_arc_t *); -static pcb_bool ListsEmpty(pcb_bool); -static pcb_bool DoIt(pcb_bool, pcb_bool); -static void DumpList(void); -static pcb_bool ListStart(pcb_any_obj_t *obj); -static pcb_bool SetThing(void *group1_obj, void *group2_obj); +static void find_int_conn(pcb_find_t *ctx, pcb_any_obj_t *from_) +{ + void *from = from_; /* for warningless comparison */ + pcb_subc_t *s; + int ic; -#include "find2.c" + s = pcb_obj_parent_subc(from_); + if (s == NULL) + return; -#include "find_lookup.c" -#include "find_misc.c" + ic = from_->intconn; + PCB_PADSTACK_LOOP(s->data); + { + if ((padstack != from) && (padstack->term != NULL) && (padstack->intconn == ic) && (!(PCB_DFLAG_TEST(&(padstack->Flags), ctx->mark)))) + if (pcb_find_addobj(ctx, (pcb_any_obj_t *)padstack, from_, PCB_FCT_INTCONN) != 0) + return; + } + PCB_END_LOOP; + PCB_LINE_COPPER_LOOP(s->data); + { + if ((line != from) && (line->term != NULL) && (line->intconn == ic) && (!(PCB_DFLAG_TEST(&(line->Flags), ctx->mark)))) + if (pcb_find_addobj(ctx, (pcb_any_obj_t *)line, from_, PCB_FCT_INTCONN) != 0) + return; + } + PCB_ENDALL_LOOP; + + PCB_ARC_COPPER_LOOP(s->data); + { + if ((arc != from) && (arc->term != NULL) && (arc->intconn == ic) && (!(PCB_DFLAG_TEST(&(arc->Flags), ctx->mark)))) + if (pcb_find_addobj(ctx, (pcb_any_obj_t *)arc, from_, PCB_FCT_INTCONN) != 0) + return; + } + PCB_ENDALL_LOOP; + + PCB_POLY_COPPER_LOOP(s->data); + { + if ((polygon != from) && (polygon->term != NULL) && (polygon->intconn == ic) && (!(PCB_DFLAG_TEST(&(polygon->Flags), ctx->mark)))) + if (pcb_find_addobj(ctx, (pcb_any_obj_t *)polygon, from_, PCB_FCT_INTCONN) != 0) + return; + } + PCB_ENDALL_LOOP; + +TODO("find: no find through text yet") +#if 0 + PCB_TEXT_COPPER_LOOP(s->data); + { + if ((text != from) && (text->term != NULL) && (text->intconn == ic) && (!(PCB_DFLAG_TEST(&(text->Flags), ctx->mark)))) + if (pcb_find_addobj(ctx, (pcb_any_obj_t *)text, from_, PCB_FCT_INTCONN) != 0) + return; + } + PCB_ENDALL_LOOP; +#endif +} + +/* return whether a and b are in the same internal-no-connection group */ +static pcb_bool int_noconn(pcb_any_obj_t *a, pcb_any_obj_t *b) +{ + pcb_subc_t *pa, *pb; + + /* cheap test: they need to have valid and matching intnoconn */ + if ((a->intnoconn == 0) || (a->intnoconn != b->intnoconn)) + return pcb_false; + + /* expensive tests: they need to be in the same subc */ + pa = pcb_obj_parent_subc(a); + if (pa == NULL) + return pcb_false; + + pb = pcb_obj_parent_subc(b); + + return (pa == pb); +} + +#define INOCONN(a,b) int_noconn((pcb_any_obj_t *)a, (pcb_any_obj_t *)b) + +#define PCB_FIND_CHECK(ctx, curr, obj, ctype, retstmt) \ + do { \ + pcb_any_obj_t *__obj__ = (pcb_any_obj_t *)obj; \ + if (!(PCB_DFLAG_TEST(&(__obj__->Flags), ctx->mark))) { \ + if (!INOCONN(curr, obj) && (pcb_intersect_obj_obj(curr, __obj__))) {\ + if (pcb_find_addobj(ctx, __obj__, curr, ctype) != 0) { retstmt; } \ + if ((__obj__->term != NULL) && (!ctx->ignore_intconn) && (__obj__->intconn > 0)) \ + find_int_conn(ctx, __obj__); \ + } \ + } \ + } while(0) + +void pcb_find_on_layer(pcb_find_t *ctx, pcb_layer_t *l, pcb_any_obj_t *curr, pcb_rtree_box_t *sb, pcb_found_conn_type_t ctype) +{ + pcb_rtree_it_t it; + pcb_box_t *n; + + if (l->line_tree != NULL) { + for(n = pcb_rtree_first(&it, l->line_tree, sb); n != NULL; n = pcb_rtree_next(&it)) + PCB_FIND_CHECK(ctx, curr, n, ctype, return); + pcb_r_end(&it); + } + + if (l->arc_tree != NULL) { + for(n = pcb_rtree_first(&it, l->arc_tree, sb); n != NULL; n = pcb_rtree_next(&it)) + PCB_FIND_CHECK(ctx, curr, n, ctype, return); + pcb_r_end(&it); + } + + if (l->polygon_tree != NULL) { + for(n = pcb_rtree_first(&it, l->polygon_tree, sb); n != NULL; n = pcb_rtree_next(&it)) + PCB_FIND_CHECK(ctx, curr, n, ctype, return); + pcb_r_end(&it); + } + + if (l->text_tree != NULL) { + for(n = pcb_rtree_first(&it, l->text_tree, sb); n != NULL; n = pcb_rtree_next(&it)) + PCB_FIND_CHECK(ctx, curr, n, ctype, return); + pcb_r_end(&it); + } +} + +void pcb_find_on_layergrp(pcb_find_t *ctx, pcb_layergrp_t *g, pcb_any_obj_t *curr, pcb_rtree_box_t *sb, pcb_found_conn_type_t ctype) +{ + int n; + if (g == NULL) + return; + for(n = 0; n < g->len; n++) + pcb_find_on_layer(ctx, &ctx->data->Layer[g->lid[n]], curr, sb, ctype); +} + +static void pcb_find_rat(pcb_find_t *ctx, pcb_rat_t *rat) +{ + pcb_rtree_box_t sb; + + sb.x1 = rat->Point1.X; sb.x2 = rat->Point1.X+1; + sb.y1 = rat->Point1.Y; sb.y2 = rat->Point1.Y+1; + pcb_find_on_layergrp(ctx, pcb_get_layergrp(ctx->pcb, rat->group1), (pcb_any_obj_t *)rat, &sb, PCB_FCT_RAT); + + sb.x1 = rat->Point2.X; sb.x2 = rat->Point2.X+1; + sb.y1 = rat->Point2.Y; sb.y2 = rat->Point2.Y+1; + pcb_find_on_layergrp(ctx, pcb_get_layergrp(ctx->pcb, rat->group2), (pcb_any_obj_t *)rat, &sb, PCB_FCT_RAT); +} + +static unsigned long pcb_find_exec(pcb_find_t *ctx) +{ + pcb_any_obj_t *curr; + pcb_found_conn_type_t ctype; + + if ((ctx->start_layergrp == NULL) && (ctx->open.used > 0) && (ctx->pcb != NULL)) { + curr = ctx->open.array[0]; + if ((curr != NULL) && (curr->parent_type == PCB_PARENT_LAYER)) { + pcb_layergrp_id_t gid = pcb_layer_get_group_(curr->parent.layer); + ctx->start_layergrp = pcb_get_layergrp(ctx->pcb, gid); + if (!ctx->allow_noncopper) { + TODO("find.c: implement this; special case: starting layer object on non-copper can still jump on padstack!"); + } + } + } + + while((ctx->open.used > 0) && (!ctx->aborted)) { + /* pop the last object, without reallocating to smaller, mark it found */ + ctx->open.used--; + curr = ctx->open.array[ctx->open.used]; + ctype = curr->type == PCB_OBJ_RAT ? PCB_FCT_RAT : PCB_FCT_COPPER; + + { /* search unmkared connections: iterative approach */ + pcb_rtree_it_t it; + pcb_box_t *n; + pcb_rtree_box_t *sb = (pcb_rtree_box_t *)&curr->bbox_naked; + + if (PCB->Data->padstack_tree != NULL) { + for(n = pcb_rtree_first(&it, PCB->Data->padstack_tree, sb); n != NULL; n = pcb_rtree_next(&it)) + PCB_FIND_CHECK(ctx, curr, n, ctype, return ctx->nfound); + pcb_r_end(&it); + } + + if ((ctx->consider_rats) && (PCB->Data->rat_tree != NULL)) { + if (PCB->Data->padstack_tree != NULL) { + for(n = pcb_rtree_first(&it, PCB->Data->rat_tree, sb); n != NULL; n = pcb_rtree_next(&it)) + PCB_FIND_CHECK(ctx, curr, n, PCB_FCT_RAT, return ctx->nfound); + pcb_r_end(&it); + } + } + + if (curr->type == PCB_OBJ_PSTK) { + int li; + pcb_layer_t *l; + if ((!ctx->stay_layergrp) || (ctx->start_layergrp == NULL)) { + for(li = 0, l = ctx->data->Layer; li < ctx->data->LayerN; li++,l++) { + if (!ctx->allow_noncopper) { + TODO("find.c: implement this"); + } + if (pcb_pstk_shape_at_(ctx->pcb, (pcb_pstk_t *)curr, l, 0)) + pcb_find_on_layer(ctx, l, curr, sb, ctype); + } + } + else { + for(li = 0; li < ctx->start_layergrp->len; li++) { + l = pcb_get_layer(ctx->data, ctx->start_layergrp->lid[li]); + if (l != NULL) + pcb_find_on_layer(ctx, l, curr, sb, ctype); + } + } + } + else if (curr->type == PCB_OBJ_RAT) { + pcb_find_rat(ctx, (pcb_rat_t *)curr); + } + else { + /* layer objects need to be checked against same layer objects only */ + assert(curr->parent_type == PCB_PARENT_LAYER); + pcb_find_on_layer(ctx, curr->parent.layer, curr, sb, ctype); + } + } + } + + if (ctx->flag_chg_undoable) + pcb_undo_inc_serial(); + + return ctx->nfound; +} + +static int pcb_find_init_(pcb_find_t *ctx, pcb_data_t *data) +{ + if (ctx->in_use) + return -1; + ctx->in_use = 1; + ctx->aborted = 0; + ctx->mark = pcb_dynflag_alloc("pcb_find_from_obj"); + ctx->data = data; + ctx->nfound = 0; + ctx->start_layergrp = NULL; + ctx->pcb = pcb_data_get_top(data); + + if (ctx->list_found) + vtp0_init(&ctx->found); + vtp0_init(&ctx->open); + return 0; +} + +unsigned long pcb_find_from_obj(pcb_find_t *ctx, pcb_data_t *data, pcb_any_obj_t *from) +{ + if (pcb_find_init_(ctx, data) < 0) + return -1; + + pcb_data_dynflag_clear(data, ctx->mark); + pcb_find_addobj(ctx, from, NULL, PCB_FCT_START); /* add the starting object with no 'arrived_from' */ + return pcb_find_exec(ctx); +} + + +unsigned long pcb_find_from_xy(pcb_find_t *ctx, pcb_data_t *data, pcb_coord_t x, pcb_coord_t y) +{ + void *ptr1, *ptr2, *ptr3; + pcb_any_obj_t *obj; + int type; + + type = pcb_search_obj_by_location(PCB_LOOKUP_FIRST, &ptr1, &ptr2, &ptr3, x, y, PCB_SLOP * pcb_pixel_slop); + if (type == PCB_OBJ_VOID) + type = pcb_search_obj_by_location(PCB_LOOKUP_MORE, &ptr1, &ptr2, &ptr3, x, y, PCB_SLOP * pcb_pixel_slop); + + if (type == PCB_OBJ_VOID) + return -1; + + obj = ptr2; + if ((obj->parent_type == PCB_PARENT_LAYER) && ((pcb_layer_flags_(obj->parent.layer) & PCB_LYT_COPPER) == 0)) + return -1; /* non-conductive object */ + + return pcb_find_from_obj(ctx, data, obj); +} + + +void pcb_find_free(pcb_find_t *ctx) +{ + if (!ctx->in_use) + return; + if (ctx->list_found) + vtp0_uninit(&ctx->found); + vtp0_uninit(&ctx->open); + pcb_dynflag_free(ctx->mark); + ctx->in_use = 0; +} + Index: trunk/src/find.h =================================================================== --- trunk/src/find.h (revision 21905) +++ trunk/src/find.h (revision 21906) @@ -2,8 +2,7 @@ * COPYRIGHT * * pcb-rnd, interactive printed circuit board design - * (this file is based on PCB, interactive printed circuit board design) - * Copyright (C) 1994,1995,1996 Thomas Nau + * Copyright (C) 2018 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 @@ -23,28 +22,81 @@ * 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") - * */ -/* Find galvanic/geometrical connections */ +/* Follow galvanic connections through overlapping objects */ -#ifndef PCB_FIND_H -#define PCB_FIND_H +#ifndef PCB_FIND2_H +#define PCB_FIND2_H -#include "config.h" -#include "obj_common.h" +#include +#include "global_typedefs.h" +#include "flag.h" -#define PCB_SILK_TYPE \ - (PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_POLY) +typedef enum { + PCB_FCT_COPPER = 1, /* copper connection */ + PCB_FCT_INTCONN = 2, /* subc internal connection, using the intconn attrib */ + PCB_FCT_RAT = 4, /* connected between a rat line and anything else */ + PCB_FCT_START = 8 /* starting object of a query */ +} pcb_found_conn_type_t; -void pcb_lookup_conn(pcb_coord_t, pcb_coord_t, pcb_bool, pcb_coord_t, int); -pcb_bool pcb_reset_conns(pcb_bool); -void pcb_conn_lookup_init(void); -void pcb_conn_lookup_uninit(void); -void pcb_rat_find_hook(pcb_any_obj_t *obj, pcb_bool undo, pcb_bool AndRats); -void pcb_save_find_flag(int); -void pcb_restore_find_flag(void); +typedef struct pcb_find_s pcb_find_t; +struct pcb_find_s { + /* public config - all-zero uses the original method, except for flag set */ + unsigned stay_layergrp:1; /* do not leave the layer (no padstack hop) */ + unsigned allow_noncopper:1; /* also run on non-copper objects */ + unsigned list_found:1; /* allow adding objects in the ->found vector */ + unsigned ignore_intconn:1; /* do not jump terminals on subc intconn */ + unsigned consider_rats:1; /* don't ignore rat lines, don't consider physical objects only */ + unsigned flag_chg_undoable:1; /* when set, and flag_set or flag_clr is non-zero, put all found objects on the flag-undo before the flag change */ + unsigned long flag_set; /* when non-zero, set the static flag bits on objects found */ + unsigned long flag_clr; /* when non-zero, remove the static flag bits on objects found */ -#include "find2.h" + /* if non-NULL, call after an object is found; if returns non-zero, + set ->aborted and stop the search. When search started from an object, + it is called for the starting object as well. All object data and ctx + fields are updated for new_obj before the call. arrived_from is + the previous object (that already triggered a callback) from which + new_obj was first found; can be NULL for the starting object. ctype + describes the relation between arrived_from and new_obj. */ + int (*found_cb)(pcb_find_t *ctx, pcb_any_obj_t *new_obj, pcb_any_obj_t *arrived_from, pcb_found_conn_type_t ctype); + /* public state/result */ + vtp0_t found; /* objects found, when list_found is 1 - of (pcb_any_obj_t *) */ + void *user_data; /* filled in by caller, not read or modified by find code */ + + /* private */ + vtp0_t open; /* objects already found but need checking for conns of (pcb_any_obj_t *) */ + pcb_data_t *data; + pcb_board_t *pcb; + pcb_layergrp_t *start_layergrp; + pcb_dynf_t mark; + unsigned long nfound; + unsigned in_use:1; + unsigned aborted:1; +}; + + +unsigned long pcb_find_from_obj(pcb_find_t *ctx, pcb_data_t *data, pcb_any_obj_t *from); +unsigned long pcb_find_from_xy(pcb_find_t *ctx, pcb_data_t *data, pcb_coord_t x, pcb_coord_t y); + +void pcb_find_free(pcb_find_t *ctx); + +/* High level intersection function: returns if a and b intersect (overlap) */ +pcb_bool pcb_intersect_obj_obj(pcb_any_obj_t *a, pcb_any_obj_t *b); + +/* Low level intersection functions: */ +pcb_bool pcb_isc_line_line(pcb_line_t *Line1, pcb_line_t *Line2); +pcb_bool pcb_isc_line_arc(pcb_line_t *Line, pcb_arc_t *Arc); +pcb_bool pcb_isc_arc_poly(pcb_arc_t *Arc, pcb_poly_t *Polygon); +pcb_bool pcb_isc_arc_polyarea(pcb_arc_t *Arc, pcb_polyarea_t *pa); +pcb_bool pcb_isc_line_poly(pcb_line_t *Line, pcb_poly_t *Polygon); +pcb_bool pcb_isc_poly_poly(pcb_poly_t *P1, pcb_poly_t *P2); +pcb_bool_t pcb_isc_pstk_line(pcb_pstk_t *ps, pcb_line_t *line); + +#define PCB_LOOKUP_FIRST \ + (PCB_OBJ_PSTK | PCB_OBJ_SUBC_PART) +#define PCB_LOOKUP_MORE \ + (PCB_OBJ_LINE | PCB_OBJ_RAT | PCB_OBJ_POLY | PCB_OBJ_ARC | PCB_OBJ_SUBC_PART) + #endif Index: trunk/src/find_geo.c =================================================================== --- trunk/src/find_geo.c (revision 21905) +++ trunk/src/find_geo.c (revision 21906) @@ -45,6 +45,7 @@ #include "macro.h" #include "obj_arc_ui.h" #include "obj_pstk_inlines.h" +#include "search.h" #define EXPAND_BOUNDS(p) if (Bloat > 0) {\ (p)->BoundingBox.X1 -= Bloat; \ Index: trunk/src/rats.c =================================================================== --- trunk/src/rats.c (revision 21905) +++ trunk/src/rats.c (revision 21906) @@ -541,7 +541,6 @@ if (!NoWarn) Warned |= CheckShorts(a->Connection[0].menu); } - pcb_reset_conns(pcb_false); return Warned; } @@ -697,11 +696,6 @@ /* so we throw it away and free the space */ pcb_net_free(&Netl->Net[--(Netl->NetN)]); /* Sadly adding a rat line messes up the sorted arrays in connection finder */ - /* hace: perhaps not necessarily now that they aren't stored in normal layers */ - if (changed) { - pcb_conn_lookup_uninit(); - pcb_conn_lookup_init(); - } return changed; } @@ -726,8 +720,6 @@ } changed = pcb_false; /* initialize finding engine */ - pcb_conn_lookup_init(); - pcb_save_find_flag(PCB_FLAG_DRC); Nets = (pcb_netlist_t *) calloc(1, sizeof(pcb_netlist_t)); /* now we build another netlist (Nets) for each * net in Wantlist that shows how it actually looks now, @@ -760,8 +752,6 @@ PCB_END_LOOP; pcb_netlist_free(Nets); free(Nets); - pcb_conn_lookup_uninit(); - pcb_restore_find_flag(); if (funcp) return pcb_true; @@ -810,9 +800,6 @@ pcb_message(PCB_MSG_WARNING, _("Can't add rat lines because no netlist is loaded.\n")); return result; } - /* initialize finding engine */ - pcb_conn_lookup_init(); - pcb_save_find_flag(PCB_FLAG_DRC); /* now we build another netlist (Nets) for each * net in Wantlist that shows how it actually looks now, * then fill in any missing connections with rat lines. @@ -842,8 +829,6 @@ GatherSubnets(Nets, SelectedOnly, pcb_false); } PCB_END_LOOP; - pcb_conn_lookup_uninit(); - pcb_restore_find_flag(); return result; } Index: trunk/src_plugins/autoroute/autoroute.c =================================================================== --- trunk/src_plugins/autoroute/autoroute.c (revision 21905) +++ trunk/src_plugins/autoroute/autoroute.c (revision 21906) @@ -4587,7 +4587,6 @@ } if (ratlist_length(&PCB->Data->Rat) == 0) return pcb_false; - pcb_save_find_flag(PCB_FLAG_DRC); rd = CreateRouteData(); if (rd == NULL) { pcb_message(PCB_MSG_ERROR, "Failed to initialize data; might be missing\n" "top or bottom copper layer.\n"); @@ -4745,7 +4744,6 @@ pcb_redraw(); } - pcb_restore_find_flag(); #if defined (ROUTE_DEBUG) aabort = 0; #endif Index: trunk/src_plugins/diag/diag.c =================================================================== --- trunk/src_plugins/diag/diag.c (revision 21905) +++ trunk/src_plugins/diag/diag.c (revision 21906) @@ -412,43 +412,6 @@ } #include "find.h" -extern void pcb_lookup_conn_by_pin(int type, void *ptr1); -static const char pcb_acts_FindPerf[] = "findperf()\n"; -static const char pcb_acth_FindPerf[] = "Measure the peformance of find.c"; -static fgw_error_t pcb_act_FindPerf(fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - double from, now, end, duration = 4.0; - long its = 0, pins = 0; - - PCB_SUBC_LOOP(PCB->Data) { - PCB_PADSTACK_LOOP(subc->data) { - pins++; - } - PCB_END_LOOP; - } - PCB_END_LOOP; - - pcb_message(PCB_MSG_INFO, "Measuring find.c peformance for %f seconds starting from %ld pins...\n", duration, pins); - - from = pcb_dtime(); - end = from + duration; - do { - PCB_SUBC_LOOP(PCB->Data) { - PCB_PADSTACK_LOOP(subc->data) { - pcb_reset_conns(0); - pcb_lookup_conn_by_pin(padstack->type, padstack); - } - PCB_END_LOOP; - } - PCB_END_LOOP; - its++; - now = pcb_dtime(); - } while(now < end); - pcb_message(PCB_MSG_INFO, "find.c peformance: %d %f pin find per second\n", its, (double)its * (double)pins / (now-from)); - PCB_ACT_IRES(0); - return 0; -} - static const char pcb_acts_Find2Perf[] = "find2perf()\n"; static const char pcb_acth_Find2Perf[] = "Measure the peformance of find2.c"; static fgw_error_t pcb_act_Find2Perf(fgw_arg_t *res, int argc, fgw_arg_t *argv) @@ -526,7 +489,6 @@ #endif {"EvalConf", pcb_act_EvalConf, pcb_acth_EvalConf, pcb_acts_EvalConf}, {"d1", pcb_act_d1, pcb_acth_d1, pcb_acts_d1}, - {"findperf", pcb_act_FindPerf, pcb_acth_FindPerf, pcb_acts_FindPerf}, {"find2perf", pcb_act_Find2Perf, pcb_acth_Find2Perf, pcb_acts_Find2Perf}, {"integrity", pcb_act_integrity, integrity_help, integrity_syntax}, {"dumpflags", pcb_act_dumpflags, pcb_acth_dumpflags, pcb_acts_dumpflags}, Index: trunk/src_plugins/lib_gtk_common/bu_dwg_tooltip.c =================================================================== --- trunk/src_plugins/lib_gtk_common/bu_dwg_tooltip.c (revision 21905) +++ trunk/src_plugins/lib_gtk_common/bu_dwg_tooltip.c (revision 21906) @@ -45,6 +45,8 @@ #define TOOLTIP_UPDATE_DELAY 200 +#define PCB_SILK_TYPE (PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_POLY) + static char *describe_location(pcb_coord_t X, pcb_coord_t Y) { void *ptr1, *ptr2, *ptr3;