/* --------------------------------------------------------------------------- * searches a polygon-point on all layers that are switched on * in layerstack order */ static bool SearchPointByLocation (int locked, LayerTypePtr * Layer, PolygonTypePtr * Polygon, PointTypePtr * Point) { double d, least; bool found = false; least = SearchRadius + MAX_POLYGON_POINT_DISTANCE; *Layer = SearchLayer; POLYGON_LOOP (*Layer); { POLYGONPOINT_LOOP (polygon); { d = Distance (point->X, point->Y, PosX, PosY); if (d < least) { least = d; *Polygon = polygon; *Point = point; found = true; } } END_LOOP; } END_LOOP; if (found) return (true); return (false); }
void MirrorBuffer (BufferType *Buffer) { int i; if (Buffer->Data->ElementN) { Message (_("You can't mirror a buffer that has elements!\n")); return; } for (i = 0; i < max_copper_layer + 2; i++) { LayerType *layer = Buffer->Data->Layer + i; if (layer->TextN) { Message (_("You can't mirror a buffer that has text!\n")); return; } } /* set buffer offset to 'mark' position */ Buffer->X = SWAP_X (Buffer->X); Buffer->Y = SWAP_Y (Buffer->Y); VIA_LOOP (Buffer->Data); { via->X = SWAP_X (via->X); via->Y = SWAP_Y (via->Y); } END_LOOP; ALLLINE_LOOP (Buffer->Data); { line->Point1.X = SWAP_X (line->Point1.X); line->Point1.Y = SWAP_Y (line->Point1.Y); line->Point2.X = SWAP_X (line->Point2.X); line->Point2.Y = SWAP_Y (line->Point2.Y); } ENDALL_LOOP; ALLARC_LOOP (Buffer->Data); { arc->X = SWAP_X (arc->X); arc->Y = SWAP_Y (arc->Y); arc->StartAngle = SWAP_ANGLE (arc->StartAngle); arc->Delta = SWAP_DELTA (arc->Delta); SetArcBoundingBox (arc); } ENDALL_LOOP; ALLPOLYGON_LOOP (Buffer->Data); { POLYGONPOINT_LOOP (polygon); { point->X = SWAP_X (point->X); point->Y = SWAP_Y (point->Y); } END_LOOP; SetPolygonBoundingBox (polygon); } ENDALL_LOOP; SetBufferBoundingBox (Buffer); SetCrosshairRangeToBuffer (); }
/* --------------------------------------------------------------------------- * low level routine to move a polygon */ void MovePolygonLowLevel (PolygonTypePtr Polygon, Coord DeltaX, Coord DeltaY) { POLYGONPOINT_LOOP (Polygon); { MOVE (point->X, point->Y, DeltaX, DeltaY); } END_LOOP; MOVE_BOX_LOWLEVEL (&Polygon->BoundingBox, DeltaX, DeltaY); }
/* --------------------------------------------------------------------------- * searches for a object by it's unique ID. It doesn't matter if * the object is visible or not. The search is performed on a PCB, a * buffer or on the remove list. * The calling routine passes two pointers to allocated memory for storing * the results. * A type value is returned too which is NO_TYPE if no objects has been found. */ int SearchObjectByID (DataTypePtr Base, void **Result1, void **Result2, void **Result3, int ID, int type) { if (type == LINE_TYPE || type == LINEPOINT_TYPE) { ALLLINE_LOOP (Base); { if (line->ID == ID) { *Result1 = (void *) layer; *Result2 = *Result3 = (void *) line; return (LINE_TYPE); } if (line->Point1.ID == ID) { *Result1 = (void *) layer; *Result2 = (void *) line; *Result3 = (void *) &line->Point1; return (LINEPOINT_TYPE); } if (line->Point2.ID == ID) { *Result1 = (void *) layer; *Result2 = (void *) line; *Result3 = (void *) &line->Point2; return (LINEPOINT_TYPE); } } ENDALL_LOOP; } if (type == ARC_TYPE) { ALLARC_LOOP (Base); { if (arc->ID == ID) { *Result1 = (void *) layer; *Result2 = *Result3 = (void *) arc; return (ARC_TYPE); } } ENDALL_LOOP; } if (type == TEXT_TYPE) { ALLTEXT_LOOP (Base); { if (text->ID == ID) { *Result1 = (void *) layer; *Result2 = *Result3 = (void *) text; return (TEXT_TYPE); } } ENDALL_LOOP; } if (type == POLYGON_TYPE || type == POLYGONPOINT_TYPE) { ALLPOLYGON_LOOP (Base); { if (polygon->ID == ID) { *Result1 = (void *) layer; *Result2 = *Result3 = (void *) polygon; return (POLYGON_TYPE); } if (type == POLYGONPOINT_TYPE) POLYGONPOINT_LOOP (polygon); { if (point->ID == ID) { *Result1 = (void *) layer; *Result2 = (void *) polygon; *Result3 = (void *) point; return (POLYGONPOINT_TYPE); } } END_LOOP; } ENDALL_LOOP; } if (type == VIA_TYPE) { VIA_LOOP (Base); { if (via->ID == ID) { *Result1 = *Result2 = *Result3 = (void *) via; return (VIA_TYPE); } } END_LOOP; } if (type == RATLINE_TYPE || type == LINEPOINT_TYPE) { RAT_LOOP (Base); { if (line->ID == ID) { *Result1 = *Result2 = *Result3 = (void *) line; return (RATLINE_TYPE); } if (line->Point1.ID == ID) { *Result1 = (void *) NULL; *Result2 = (void *) line; *Result3 = (void *) &line->Point1; return (LINEPOINT_TYPE); } if (line->Point2.ID == ID) { *Result1 = (void *) NULL; *Result2 = (void *) line; *Result3 = (void *) &line->Point2; return (LINEPOINT_TYPE); } } END_LOOP; } if (type == ELEMENT_TYPE || type == PAD_TYPE || type == PIN_TYPE || type == ELEMENTLINE_TYPE || type == ELEMENTNAME_TYPE || type == ELEMENTARC_TYPE) /* check pins and elementnames too */ ELEMENT_LOOP (Base); { if (element->ID == ID) { *Result1 = *Result2 = *Result3 = (void *) element; return (ELEMENT_TYPE); } if (type == ELEMENTLINE_TYPE) ELEMENTLINE_LOOP (element); { if (line->ID == ID) { *Result1 = (void *) element; *Result2 = *Result3 = (void *) line; return (ELEMENTLINE_TYPE); } } END_LOOP; if (type == ELEMENTARC_TYPE) ARC_LOOP (element); { if (arc->ID == ID) { *Result1 = (void *) element; *Result2 = *Result3 = (void *) arc; return (ELEMENTARC_TYPE); } } END_LOOP; if (type == ELEMENTNAME_TYPE) ELEMENTTEXT_LOOP (element); { if (text->ID == ID) { *Result1 = (void *) element; *Result2 = *Result3 = (void *) text; return (ELEMENTNAME_TYPE); } } END_LOOP; if (type == PIN_TYPE) PIN_LOOP (element); { if (pin->ID == ID) { *Result1 = (void *) element; *Result2 = *Result3 = (void *) pin; return (PIN_TYPE); } } END_LOOP; if (type == PAD_TYPE) PAD_LOOP (element); { if (pad->ID == ID) { *Result1 = (void *) element; *Result2 = *Result3 = (void *) pad; return (PAD_TYPE); } } END_LOOP; } END_LOOP; Message ("hace: Internal error, search for ID %d failed\n", ID); return (NO_TYPE); }
/* --------------------------------------------------------------------------- * flip components/tracks from one side to the other */ static void SwapBuffer (BufferType *Buffer) { int j, k; Cardinal sgroup, cgroup; LayerType swap; ELEMENT_LOOP (Buffer->Data); { r_delete_element (Buffer->Data, element); MirrorElementCoordinates (Buffer->Data, element, 0); } END_LOOP; /* set buffer offset to 'mark' position */ Buffer->X = SWAP_X (Buffer->X); Buffer->Y = SWAP_Y (Buffer->Y); VIA_LOOP (Buffer->Data); { r_delete_entry (Buffer->Data->via_tree, (BoxType *)via); via->X = SWAP_X (via->X); via->Y = SWAP_Y (via->Y); SetPinBoundingBox (via); r_insert_entry (Buffer->Data->via_tree, (BoxType *)via, 0); } END_LOOP; ALLLINE_LOOP (Buffer->Data); { r_delete_entry (layer->line_tree, (BoxType *)line); line->Point1.X = SWAP_X (line->Point1.X); line->Point1.Y = SWAP_Y (line->Point1.Y); line->Point2.X = SWAP_X (line->Point2.X); line->Point2.Y = SWAP_Y (line->Point2.Y); SetLineBoundingBox (line); r_insert_entry (layer->line_tree, (BoxType *)line, 0); } ENDALL_LOOP; ALLARC_LOOP (Buffer->Data); { r_delete_entry (layer->arc_tree, (BoxType *)arc); arc->X = SWAP_X (arc->X); arc->Y = SWAP_Y (arc->Y); arc->StartAngle = SWAP_ANGLE (arc->StartAngle); arc->Delta = SWAP_DELTA (arc->Delta); SetArcBoundingBox (arc); r_insert_entry (layer->arc_tree, (BoxType *)arc, 0); } ENDALL_LOOP; ALLPOLYGON_LOOP (Buffer->Data); { r_delete_entry (layer->polygon_tree, (BoxType *)polygon); POLYGONPOINT_LOOP (polygon); { point->X = SWAP_X (point->X); point->Y = SWAP_Y (point->Y); } END_LOOP; SetPolygonBoundingBox (polygon); r_insert_entry (layer->polygon_tree, (BoxType *)polygon, 0); /* hmmm, how to handle clip */ } ENDALL_LOOP; ALLTEXT_LOOP (Buffer->Data); { r_delete_entry (layer->text_tree, (BoxType *)text); text->X = SWAP_X (text->X); text->Y = SWAP_Y (text->Y); TOGGLE_FLAG (ONSOLDERFLAG, text); SetTextBoundingBox (&PCB->Font, text); r_insert_entry (layer->text_tree, (BoxType *)text, 0); } ENDALL_LOOP; /* swap silkscreen layers */ swap = Buffer->Data->Layer[solder_silk_layer]; Buffer->Data->Layer[solder_silk_layer] = Buffer->Data->Layer[component_silk_layer]; Buffer->Data->Layer[component_silk_layer] = swap; /* swap layer groups when balanced */ sgroup = GetLayerGroupNumberByNumber (solder_silk_layer); cgroup = GetLayerGroupNumberByNumber (component_silk_layer); if (PCB->LayerGroups.Number[cgroup] == PCB->LayerGroups.Number[sgroup]) { for (j = k = 0; j < PCB->LayerGroups.Number[sgroup]; j++) { int t1, t2; Cardinal cnumber = PCB->LayerGroups.Entries[cgroup][k]; Cardinal snumber = PCB->LayerGroups.Entries[sgroup][j]; if (snumber >= max_copper_layer) continue; swap = Buffer->Data->Layer[snumber]; while (cnumber >= max_copper_layer) { k++; cnumber = PCB->LayerGroups.Entries[cgroup][k]; } Buffer->Data->Layer[snumber] = Buffer->Data->Layer[cnumber]; Buffer->Data->Layer[cnumber] = swap; k++; /* move the thermal flags with the layers */ ALLPIN_LOOP (Buffer->Data); { t1 = TEST_THERM (snumber, pin); t2 = TEST_THERM (cnumber, pin); ASSIGN_THERM (snumber, t2, pin); ASSIGN_THERM (cnumber, t1, pin); } ENDALL_LOOP; VIA_LOOP (Buffer->Data); { t1 = TEST_THERM (snumber, via); t2 = TEST_THERM (cnumber, via); ASSIGN_THERM (snumber, t2, via); ASSIGN_THERM (cnumber, t1, via); } END_LOOP; } } SetBufferBoundingBox (Buffer); SetCrosshairRangeToBuffer (); }
void FreeRotateBuffer (BufferType *Buffer, Angle angle) { double cosa, sina; cosa = cos(angle * M_PI/180.0); sina = sin(angle * M_PI/180.0); /* rotate vias */ VIA_LOOP (Buffer->Data); { r_delete_entry (Buffer->Data->via_tree, (BoxType *)via); free_rotate (&via->X, &via->Y, Buffer->X, Buffer->Y, cosa, sina); SetPinBoundingBox (via); r_insert_entry (Buffer->Data->via_tree, (BoxType *)via, 0); } END_LOOP; /* elements */ ELEMENT_LOOP (Buffer->Data); { FreeRotateElementLowLevel (Buffer->Data, element, Buffer->X, Buffer->Y, cosa, sina, angle); } END_LOOP; /* all layer related objects */ ALLLINE_LOOP (Buffer->Data); { r_delete_entry (layer->line_tree, (BoxType *)line); free_rotate (&line->Point1.X, &line->Point1.Y, Buffer->X, Buffer->Y, cosa, sina); free_rotate (&line->Point2.X, &line->Point2.Y, Buffer->X, Buffer->Y, cosa, sina); SetLineBoundingBox (line); r_insert_entry (layer->line_tree, (BoxType *)line, 0); } ENDALL_LOOP; ALLARC_LOOP (Buffer->Data); { r_delete_entry (layer->arc_tree, (BoxType *)arc); free_rotate (&arc->X, &arc->Y, Buffer->X, Buffer->Y, cosa, sina); arc->StartAngle = NormalizeAngle (arc->StartAngle + angle); r_insert_entry (layer->arc_tree, (BoxType *)arc, 0); } ENDALL_LOOP; /* FIXME: rotate text */ ALLPOLYGON_LOOP (Buffer->Data); { r_delete_entry (layer->polygon_tree, (BoxType *)polygon); POLYGONPOINT_LOOP (polygon); { free_rotate (&point->X, &point->Y, Buffer->X, Buffer->Y, cosa, sina); } END_LOOP; SetPolygonBoundingBox (polygon); r_insert_entry (layer->polygon_tree, (BoxType *)polygon, 0); } ENDALL_LOOP; SetBufferBoundingBox (Buffer); SetCrosshairRangeToBuffer (); }