/* * COPYRIGHT * * cschem - modular/flexible schematics editor - libcschem (core library) * Copyright (C) 2022 Tibor 'Igor2' Palinkas * * (Supported by NLnet NGI0 PET Fund in 2022) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version.* * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 31 Milk Street, # 960789 Boston, MA 02196 USA * * Contact: * Project page: http://repo.hu/projects/sch-rnd * contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html * mailing list: http://www.repo.hu/projects/sch-rnd/contact.html */ #include "config.h" #include "concrete.h" #include "cnc_line.h" #include "cnc_arc.h" #include "cnc_poly.h" #include "cnc_grp.h" #include #include #include #include "intersect.h" static long csch_obj_intersect_obj_(csch_chdr_t *o1, csch_chdr_t *o2, g2d_vect_t **iscp, long *iscp_len); RND_INLINE void isc_append(g2d_vect_t **dst, long *dst_len, g2d_vect_t *src, long src_len) { long n; for(n = 0; n < src_len; n++) { if (*dst_len == 0) return; **dst = *src; (*dst)++; (*dst_len)--; src++; } } RND_INLINE long isc_ll(csch_line_t *l1, csch_line_t *l2, g2d_vect_t **iscp, long *iscp_len) { if (*iscp != NULL) { g2d_vect_t ip[2]; int res = g2d_iscp_cline_cline(&l1->inst.c, &l2->inst.c, ip, NULL); isc_append(iscp, iscp_len, ip, res); return res; } else return g2d_isc_sline_sline(&l1->inst, &l2->inst); } RND_INLINE long isc_la(csch_line_t *l, csch_arc_t *a, g2d_vect_t **iscp, long *iscp_len) { if (*iscp != NULL) { g2d_vect_t ip[2]; int res = g2d_iscp_cline_carc(&l->inst.c, &a->inst.c, ip, NULL, 0); isc_append(iscp, iscp_len, ip, res); return 0; } else return g2d_isc_sline_sarc(&l->inst, &a->inst); } RND_INLINE long isc_aa(csch_arc_t *a1, csch_arc_t *a2, g2d_vect_t **iscp, long *iscp_len) { TODO("g2d needs arc-arc intersection calculations"); return 0; } RND_INLINE long isc_po(csch_cpoly_t *p, csch_chdr_t *o, g2d_vect_t **iscp, long *iscp_len) { long n, res = 0; for(n = 0; n < p->outline.used; n++) { csch_chdr_t *po = &p->outline.array[n].hdr; res += csch_obj_intersect_obj_(po, o, iscp, iscp_len); } return res; } RND_INLINE long isc_pp(csch_cpoly_t *p1, csch_cpoly_t *p2, g2d_vect_t **iscp, long *iscp_len) { long n, res = 0; for(n = 0; n < p1->outline.used; n++) { csch_chdr_t *po = &p1->outline.array[n].hdr; res += isc_po(p2, po, iscp, iscp_len); } return res; } RND_INLINE long isc_go(csch_cgrp_t *g, csch_chdr_t *o, g2d_vect_t **iscp, long *iscp_len) { long res = 0; htip_entry_t *e; for(e = htip_first(&g->id2obj); e != NULL; e = htip_next(&g->id2obj, e)) { csch_chdr_t *go = e->value; res += csch_obj_intersect_obj_(go, o, iscp, iscp_len); } return res; } RND_INLINE long isc_gg(csch_cgrp_t *g1, csch_cgrp_t *g2, g2d_vect_t **iscp, long *iscp_len) { long res = 0; htip_entry_t *e; for(e = htip_first(&g1->id2obj); e != NULL; e = htip_next(&g1->id2obj, e)) { csch_chdr_t *go = e->value; res += isc_go(g2, go, iscp, iscp_len); } return res; } static long csch_obj_intersect_obj_(csch_chdr_t *o1, csch_chdr_t *o2, g2d_vect_t **iscp, long *iscp_len) { switch(o1->type) { case CSCH_CTYPE_LINE: switch(o2->type) { case CSCH_CTYPE_LINE: return isc_ll((csch_line_t *)o1, (csch_line_t *)o2, iscp, iscp_len); case CSCH_CTYPE_ARC: return isc_la((csch_line_t *)o1, (csch_arc_t *)o2, iscp, iscp_len); case CSCH_CTYPE_POLY: return isc_po((csch_cpoly_t *)o2, o1, iscp, iscp_len); case CSCH_CTYPE_GRP: /* intentional fall-through */ case CSCH_CTYPE_GRP_REF: return isc_go((csch_cgrp_t *)o2, o1, iscp, iscp_len); case CSCH_CTYPE_TEXT: return 0; case CSCH_CTYPE_BITMAP: return 0; case CSCH_CTYPE_CONN: return 0; case CSCH_CTYPE_PEN: return 0; case CSCH_CTYPE_invalid: return 0; case CSCH_CTYPE_max: return 0; } return 0; case CSCH_CTYPE_ARC: switch(o2->type) { case CSCH_CTYPE_LINE: return isc_la((csch_line_t *)o2, (csch_arc_t *)o1, iscp, iscp_len); case CSCH_CTYPE_ARC: return isc_aa((csch_arc_t *)o2, (csch_arc_t *)o1, iscp, iscp_len); case CSCH_CTYPE_POLY: return isc_po((csch_cpoly_t *)o2, o1, iscp, iscp_len); case CSCH_CTYPE_GRP: /* intentional fall-through */ case CSCH_CTYPE_GRP_REF: return isc_go((csch_cgrp_t *)o2, o1, iscp, iscp_len); case CSCH_CTYPE_TEXT: return 0; case CSCH_CTYPE_BITMAP: return 0; case CSCH_CTYPE_CONN: return 0; case CSCH_CTYPE_PEN: return 0; case CSCH_CTYPE_invalid: return 0; case CSCH_CTYPE_max: return 0; } return 0; case CSCH_CTYPE_POLY: switch(o2->type) { case CSCH_CTYPE_LINE: /* intentional fall-through */ case CSCH_CTYPE_ARC: return isc_po((csch_cpoly_t *)o1, o2, iscp, iscp_len); case CSCH_CTYPE_POLY: return isc_pp((csch_cpoly_t *)o1, (csch_cpoly_t *)o2, iscp, iscp_len); case CSCH_CTYPE_GRP: /* intentional fall-through */ case CSCH_CTYPE_GRP_REF: return isc_go((csch_cgrp_t *)o2, o1, iscp, iscp_len); case CSCH_CTYPE_TEXT: return 0; case CSCH_CTYPE_BITMAP: return 0; case CSCH_CTYPE_CONN: return 0; case CSCH_CTYPE_PEN: return 0; case CSCH_CTYPE_invalid: return 0; case CSCH_CTYPE_max: return 0; } return 0; case CSCH_CTYPE_GRP: case CSCH_CTYPE_GRP_REF: switch(o2->type) { case CSCH_CTYPE_LINE: /* intentional fall-through */ case CSCH_CTYPE_ARC: /* intentional fall-through */ case CSCH_CTYPE_POLY: return isc_go((csch_cgrp_t *)o1, o2, iscp, iscp_len); case CSCH_CTYPE_GRP: /* intentional fall-through */ case CSCH_CTYPE_GRP_REF: return isc_gg((csch_cgrp_t *)o1, (csch_cgrp_t *)o2, iscp, iscp_len); case CSCH_CTYPE_TEXT: return 0; case CSCH_CTYPE_BITMAP: return 0; case CSCH_CTYPE_CONN: return 0; case CSCH_CTYPE_PEN: return 0; case CSCH_CTYPE_invalid: return 0; case CSCH_CTYPE_max: return 0; } return 0; case CSCH_CTYPE_TEXT: case CSCH_CTYPE_BITMAP: case CSCH_CTYPE_CONN: case CSCH_CTYPE_PEN: case CSCH_CTYPE_invalid: case CSCH_CTYPE_max: return 0; } return 0; } long csch_obj_intersect_obj(csch_sheet_t *sheet, csch_chdr_t *o1, csch_chdr_t *o2, g2d_vect_t *iscp, long iscp_len) { return csch_obj_intersect_obj_(o1, o2, &iscp, &iscp_len); }