Index: trunk/src/thermal.c =================================================================== --- trunk/src/thermal.c (revision 12410) +++ trunk/src/thermal.c (revision 12411) @@ -24,6 +24,7 @@ #include "thermal.h" #include "obj_pinvia_therm.h" +#include "polygon.h" pcb_thermal_t pcb_thermal_str2bits(const char *str) { @@ -67,12 +68,89 @@ pcb_polyarea_t *pcb_thermal_area_pin(pcb_board_t *pcb, pcb_pin_t *pin, pcb_layer_id_t lid) { - ThermPoly(pcb, pin, lid); + return ThermPoly(pcb, pin, lid); } pcb_polyarea_t *pcb_thermal_area_line(pcb_board_t *pcb, pcb_line_t *line, pcb_layer_id_t lid) { + pcb_polyarea_t *pa, *pb, *pc; + double dx, dy, len, vx, vy, nx, ny, clr, clrth, sa, ea, e1x, e1y, e2x, e2y; + pcb_line_t ltmp; + pcb_arc_t atmp; + if ((line->Point1.X == line->Point2.X) && (line->Point1.Y == line->Point2.Y)) { + /* conrer case zero-long line is a circle: do the same as for vias */ +#warning thermal TODO + abort(); + } + + dx = line->Point1.X - line->Point2.X; + dy = line->Point1.Y - line->Point2.Y; + len = sqrt(dx*dx + dy*dy); + vx = dx / len; + vy = dy / len; + nx = -vy; + ny = vx; + clr = line->Clearance / 2; + clrth = (line->Clearance/2 + line->Thickness) / 2; + + assert(line->thermal & PCB_THERMAL_ON); /* caller should have checked this */ + switch(line->thermal & 3) { + case PCB_THERMAL_NOSHAPE: + case PCB_THERMAL_SOLID: return 0; + + case PCB_THERMAL_ROUND: + if (line->thermal & PCB_THERMAL_DIAGONAL) { + ltmp.Flags = pcb_no_flags(); + ltmp.Point1.X = line->Point1.X - clrth * nx - clr * vx * 0.75; + ltmp.Point1.Y = line->Point1.Y - clrth * ny - clr * vy * 0.75; + ltmp.Point2.X = line->Point2.X - clrth * nx + clr * vx * 0.75; + ltmp.Point2.Y = line->Point2.Y - clrth * ny + clr * vy * 0.75; + pa = pcb_poly_from_line(<mp, clr); + + ltmp.Point1.X = line->Point1.X + clrth * nx - clr * vx * 0.75; + ltmp.Point1.Y = line->Point1.Y + clrth * ny - clr * vy * 0.75; + ltmp.Point2.X = line->Point2.X + clrth * nx + clr * vx * 0.75; + ltmp.Point2.Y = line->Point2.Y + clrth * ny + clr * vy * 0.75; + pb = pcb_poly_from_line(<mp, clr); + + pcb_polyarea_boolean_free(pa, pb, &pc, PCB_PBO_UNITE); + + pa = pc; pc = NULL; + + e1x = line->Point1.X - clrth * nx + clr * vx * 2.0; + e1y = line->Point1.Y - clrth * ny + clr * vy * 2.0; + e2x = line->Point1.X + clrth * nx + clr * vx * 2.0; + e2y = line->Point1.Y + clrth * ny + clr * vy * 2.0; + sa = atan2(-(e1y - line->Point1.Y), e1x - line->Point1.X) * PCB_RAD_TO_DEG + 180.0; + ea = atan2(-(e2y - line->Point1.Y), e2x - line->Point1.X) * PCB_RAD_TO_DEG + 180.0; + + printf("sa=%f ea=%f diff=%f\n", sa, ea, ea-sa); + + atmp.Flags = pcb_no_flags(); + atmp.X = line->Point1.X; + atmp.Y = line->Point1.Y; + + if (ea-sa < 180) { + atmp.StartAngle = sa; + atmp.Delta = ea-sa; + } + else { + atmp.StartAngle = ea; + atmp.Delta = 100; + } + atmp.Width = atmp.Height = clrth; + pb = pcb_poly_from_arc(&atmp, clr); + + pcb_polyarea_boolean_free(pa, pb, &pc, PCB_PBO_UNITE); + + return pc; + } + + case PCB_THERMAL_SHARP: + break; + } + return NULL; } pcb_polyarea_t *pcb_thermal_area(pcb_board_t *pcb, pcb_any_obj_t *obj, pcb_layer_id_t lid)