Esempio n. 1
0
/* ---------------------------------------------------------------------------
 * Update the X, Y and group position information stored in the NetList after
 * elements have possibly been moved, rotated, flipped, etc.
 */
static void
UpdateXY (NetListType *Nets)
{
  Cardinal top_group, bottom_group;
  Cardinal i, j;
  /* find layer groups of the top and bottom sides */
  top_group = GetLayerGroupNumberBySide (TOP_SIDE);
  bottom_group = GetLayerGroupNumberBySide (BOTTOM_SIDE);
  /* update all nets */
  for (i = 0; i < Nets->NetN; i++)
    {
      for (j = 0; j < Nets->Net[i].ConnectionN; j++)
	{
	  ConnectionType *c = &(Nets->Net[i].Connection[j]);
	  switch (c->type)
	    {
	    case PAD_TYPE:
	      c->group = TEST_FLAG (ONSOLDERFLAG, (ElementType *) c->ptr1)
	                  ? bottom_group : top_group;
	      c->X = ((PadType *) c->ptr2)->Point1.X;
	      c->Y = ((PadType *) c->ptr2)->Point1.Y;
	      break;
	    case PIN_TYPE:
	      c->group = bottom_group;  /* any layer will do */
	      c->X = ((PinType *) c->ptr2)->X;
	      c->Y = ((PinType *) c->ptr2)->Y;
	      break;
	    default:
	      Message ("Odd connection type encountered in " "UpdateXY");
	      break;
	    }
	}
    }
}
Esempio n. 2
0
static int
info (int argc, char **argv, Coord x, Coord y)
{
  int i, j;
  int top_group, bottom_group;
  if (!PCB || !PCB->Data || !PCB->Filename)
    {
      printf("No PCB loaded.\n");
      return 0;
    }
  printf("Filename: %s\n", PCB->Filename);
  pcb_printf("Size: %ml x %ml mils, %mm x %mm mm\n",
	 PCB->MaxWidth, PCB->MaxHeight,
	 PCB->MaxWidth, PCB->MaxHeight);
  top_group = GetLayerGroupNumberBySide (TOP_SIDE);
  bottom_group = GetLayerGroupNumberBySide (BOTTOM_SIDE);
  for (i=0; i<MAX_LAYER; i++)
    {
      
      int lg = GetLayerGroupNumberByNumber (i);
      for (j = 0; j < MAX_GROUP; j++)
	putchar(j==lg ? '#' : '-');
      printf(" %c %s\n", lg == top_group ? 'c' : lg == bottom_group ? 's' : '-',
	     PCB->Data->Layer[i].Name);
    }
  return 0;
}
Esempio n. 3
0
/*!
 * \brief Checks all visible lines which belong to the same layergroup
 * as the passed pad.
 *
 * If one of the endpoints of the line lays inside the pad, the line is
 * added to the 'rubberband' list.
 */
static void
CheckPadForRubberbandConnection (PadType *Pad)
{
  Coord half = Pad->Thickness / 2;
  Cardinal group;
  struct rubber_info info;

  info.box.X1 = MIN (Pad->Point1.X, Pad->Point2.X) - half;
  info.box.Y1 = MIN (Pad->Point1.Y, Pad->Point2.Y) - half;
  info.box.X2 = MAX (Pad->Point1.X, Pad->Point2.X) + half;
  info.box.Y2 = MAX (Pad->Point1.Y, Pad->Point2.Y) + half;
  info.radius = 0;
  info.line = NULL;
  group = GetLayerGroupNumberBySide (
      TEST_FLAG (ONSOLDERFLAG, Pad) ? BOTTOM_SIDE : TOP_SIDE);

  /* check all visible layers in the same group */
  GROUP_LOOP (PCB->Data, group);
  {
    /* check all visible lines of the group member */
    info.layer = layer;
    if (info.layer->On)
      {
	r_search (info.layer->line_tree, &info.box, NULL, rubber_callback,
		  &info);
      }
  }
  END_LOOP;
}
Esempio n. 4
0
static void
CheckPadForRat (PadType *Pad)
{
  struct rinfo info;

  info.group = GetLayerGroupNumberBySide (
                  TEST_FLAG (ONSOLDERFLAG, Pad) ? BOTTOM_SIDE : TOP_SIDE);
  info.pad = Pad;
  info.type = PAD_TYPE;

  r_search (PCB->Data->rat_tree, &Pad->BoundingBox, NULL, rat_callback,
	    &info);
}
Esempio n. 5
0
File: rats.c Progetto: rlutz/pcb
/*!
 * \brief This function is moved from the original netlist.c as
 * part of the gui code separation for the Gtk port.
 */
RatType *
AddNet (void)
{
  static int ratDrawn = 0;
  char name1[256], *name2;
  Cardinal group1, group2;
  char ratname[20];
  int found;
  void *ptr1, *ptr2, *ptr3;
  LibraryMenuType *menu;
  LibraryEntryType *entry;

  if (Crosshair.AttachedLine.Point1.X == Crosshair.AttachedLine.Point2.X
      && Crosshair.AttachedLine.Point1.Y == Crosshair.AttachedLine.Point2.Y)
    return (NULL);

  found = SearchObjectByLocation (PAD_TYPE | PIN_TYPE, &ptr1, &ptr2, &ptr3,
				  Crosshair.AttachedLine.Point1.X,
				  Crosshair.AttachedLine.Point1.Y, 5);
  if (found == NO_TYPE)
    {
      Message (_("No pad/pin under rat line\n"));
      return (NULL);
    }
  if (NAMEONPCB_NAME ((ElementType *) ptr1) == NULL
      || *NAMEONPCB_NAME ((ElementType *) ptr1) == 0)
    {
      Message (_("You must name the starting element first\n"));
      return (NULL);
    }

  /* will work for pins to since the FLAG is common */
  group1 = GetLayerGroupNumberBySide (
            TEST_FLAG (ONSOLDERFLAG, (PadType *) ptr2) ? BOTTOM_SIDE : TOP_SIDE);
  strcpy (name1, ConnectionName (found, ptr1, ptr2));
  found = SearchObjectByLocation (PAD_TYPE | PIN_TYPE, &ptr1, &ptr2, &ptr3,
				  Crosshair.AttachedLine.Point2.X,
				  Crosshair.AttachedLine.Point2.Y, 5);
  if (found == NO_TYPE)
    {
      Message (_("No pad/pin under rat line\n"));
      return (NULL);
    }
  if (NAMEONPCB_NAME ((ElementType *) ptr1) == NULL
      || *NAMEONPCB_NAME ((ElementType *) ptr1) == 0)
    {
      Message (_("You must name the ending element first\n"));
      return (NULL);
    }
  group2 = GetLayerGroupNumberBySide (
            TEST_FLAG (ONSOLDERFLAG, (PadType *) ptr2) ? BOTTOM_SIDE : TOP_SIDE);
  name2 = ConnectionName (found, ptr1, ptr2);

  menu = netnode_to_netname (name1);
  if (menu)
    {
      if (netnode_to_netname (name2))
	{
	  Message (_
		   ("Both connections already in netlist - cannot merge nets\n"));
	  return (NULL);
	}
      entry = GetLibraryEntryMemory (menu);
      entry->ListEntry = strdup (name2);
      netnode_to_netname (name2);
      goto ratIt;
    }
  /* ok, the first name did not belong to a net */
  menu = netnode_to_netname (name2);
  if (menu)
    {
      entry = GetLibraryEntryMemory (menu);
      entry->ListEntry = strdup (name1);
      netnode_to_netname (name1);
      goto ratIt;
    }

  /*
   * neither belong to a net, so create a new one.
   *
   * before creating a new rats here, we need to search
   * for a unique name.
   */
  sprintf (ratname, "  ratDrawn%i", ++ratDrawn);
  while (rat_used (ratname))
    {
      sprintf (ratname, "  ratDrawn%i", ++ratDrawn);
    }

  menu = GetLibraryMenuMemory (&PCB->NetlistLib);
  menu->Name = strdup (ratname);
  entry = GetLibraryEntryMemory (menu);
  entry->ListEntry = strdup (name1);
  entry = GetLibraryEntryMemory (menu);
  entry->ListEntry = strdup (name2);
  menu->flag = 1;

ratIt:
  NetlistChanged (0);
  return (CreateNewRat (PCB->Data, Crosshair.AttachedLine.Point1.X,
			Crosshair.AttachedLine.Point1.Y,
			Crosshair.AttachedLine.Point2.X,
			Crosshair.AttachedLine.Point2.Y,
			group1, group2, Settings.RatThickness, NoFlags ()));
}
Esempio n. 6
0
File: rats.c Progetto: rlutz/pcb
/*!
 * \brief Read the library-netlist build a true Netlist structure.
 */
NetListType *
ProcNetlist (LibraryType *net_menu)
{
  ConnectionType *connection;
  ConnectionType LastPoint;
  NetType *net;
  static NetListType *Wantlist = NULL;

  if (!net_menu->MenuN)
    return (NULL);
  FreeNetListMemory (Wantlist);
  free (Wantlist);
  badnet = false;

  /* find layer groups of the component side and solder side */
  bottom_group = GetLayerGroupNumberBySide (BOTTOM_SIDE);
  top_group = GetLayerGroupNumberBySide (TOP_SIDE);

  Wantlist = (NetListType *)calloc (1, sizeof (NetListType));
  if (Wantlist)
    {
      ALLPIN_LOOP (PCB->Data);
      {
	pin->Spare = NULL;
	CLEAR_FLAG (DRCFLAG, pin);
      }
      ENDALL_LOOP;
      ALLPAD_LOOP (PCB->Data);
      {
	pad->Spare = NULL;
	CLEAR_FLAG (DRCFLAG, pad);
      }
      ENDALL_LOOP;
      MENU_LOOP (net_menu);
      {
	if (menu->Name[0] == '*' || menu->flag == 0)
	  {
	    badnet = true;
	    continue;
	  }
	net = GetNetMemory (Wantlist);
	if (menu->Style)
	  {
	    STYLE_LOOP (PCB);
	    {
	      if (style->Name && !NSTRCMP (style->Name, menu->Style))
		{
		  net->Style = style;
		  break;
		}
	    }
	    END_LOOP;
	  }
	else			/* default to NULL if none found */
	  net->Style = NULL;
	ENTRY_LOOP (menu);
	{
	  if (SeekPad (entry, &LastPoint, false))
	    {
	      if (TEST_FLAG (DRCFLAG, (PinType *) LastPoint.ptr2))
		Message (_
			 ("Error! Element %s pin %s appears multiple times in the netlist file.\n"),
			 NAMEONPCB_NAME ((ElementType *) LastPoint.ptr1),
			 (LastPoint.type ==
			  PIN_TYPE) ? ((PinType *) LastPoint.ptr2)->
			 Number : ((PadType *) LastPoint.ptr2)->Number);
	      else
		{
		  connection = GetConnectionMemory (net);
		  *connection = LastPoint;
		  /* indicate expect net */
		  connection->menu = menu;
		  /* mark as visited */
		  SET_FLAG (DRCFLAG, (PinType *) LastPoint.ptr2);
		  if (LastPoint.type == PIN_TYPE)
		    ((PinType *) LastPoint.ptr2)->Spare = (void *) menu;
		  else
		    ((PadType *) LastPoint.ptr2)->Spare = (void *) menu;
		}
	    }
	  else
	    badnet = true;
	  /* check for more pins with the same number */
	  for (; SeekPad (entry, &LastPoint, true);)
	    {
	      connection = GetConnectionMemory (net);
	      *connection = LastPoint;
	      /* indicate expect net */
	      connection->menu = menu;
	      /* mark as visited */
	      SET_FLAG (DRCFLAG, (PinType *) LastPoint.ptr2);
	      if (LastPoint.type == PIN_TYPE)
		((PinType *) LastPoint.ptr2)->Spare = (void *) menu;
	      else
		((PadType *) LastPoint.ptr2)->Spare = (void *) menu;
	    }
	}
	END_LOOP;
      }
      END_LOOP;
    }
  /* clear all visit marks */
  ALLPIN_LOOP (PCB->Data);
  {
    CLEAR_FLAG (DRCFLAG, pin);
  }
  ENDALL_LOOP;
  ALLPAD_LOOP (PCB->Data);
  {
    CLEAR_FLAG (DRCFLAG, pad);
  }
  ENDALL_LOOP;
  return (Wantlist);
}
Esempio n. 7
0
/*---------------------------------------------------------------------------
 *
 * convert buffer contents into an element
 */
bool
ConvertBufferToElement (BufferType *Buffer)
{
  ElementType *Element;
  Cardinal group;
  Cardinal pin_n = 1;
  bool hasParts = false, crooked = false;
  int onsolder;
  bool warned = false;

  if (Buffer->Data->pcb == 0)
    Buffer->Data->pcb = PCB;

  Element = CreateNewElement (PCB->Data, &PCB->Font, NoFlags (),
			      NULL, NULL, NULL, PASTEBUFFER->X,
			      PASTEBUFFER->Y, 0, 100,
			      MakeFlags (SWAP_IDENT ? ONSOLDERFLAG : NOFLAG),
			      false);
  if (!Element)
    return (false);
  VIA_LOOP (Buffer->Data);
  {
    char num[8];
    if (via->Mask < via->Thickness)
      via->Mask = via->Thickness + 2 * MASKFRAME;
    if (via->Name)
      CreateNewPin (Element, via->X, via->Y, via->Thickness,
		    via->Clearance, via->Mask, via->DrillingHole,
		    NULL, via->Name, MaskFlags (via->Flags,
						VIAFLAG | NOCOPY_FLAGS |
						SELECTEDFLAG | WARNFLAG));
    else
      {
	sprintf (num, "%d", pin_n++);
	CreateNewPin (Element, via->X, via->Y, via->Thickness,
		      via->Clearance, via->Mask, via->DrillingHole,
		      NULL, num, MaskFlags (via->Flags,
					    VIAFLAG | NOCOPY_FLAGS | SELECTEDFLAG
					    | WARNFLAG));
      }
    hasParts = true;
  }
  END_LOOP;

  for (onsolder = 0; onsolder < 2; onsolder ++)
    {
      int side;
      int onsolderflag;

      if ((!onsolder) == (!SWAP_IDENT))
	{
	  side = TOP_SIDE;
	  onsolderflag = NOFLAG;
	}
      else
	{
	  side = BOTTOM_SIDE;
	  onsolderflag = ONSOLDERFLAG;
	}

#define MAYBE_WARN() \
	  if (onsolder && !hasParts && !warned) \
	    { \
	      warned = true; \
	      Message \
		(_("Warning: All of the pads are on the opposite\n" \
		   "side from the component - that's probably not what\n" \
		   "you wanted\n")); \
	    } \

      /* get the component-side SM pads */
      group = GetLayerGroupNumberBySide (side);
      GROUP_LOOP (Buffer->Data, group);
      {
	char num[8];
	LINE_LOOP (layer);
	{
	  sprintf (num, "%d", pin_n++);
	  CreateNewPad (Element, line->Point1.X,
			line->Point1.Y, line->Point2.X,
			line->Point2.Y, line->Thickness,
			line->Clearance,
			line->Thickness + line->Clearance, NULL,
			line->Number ? line->Number : num,
			MakeFlags (onsolderflag));
	  MAYBE_WARN();
	  hasParts = true;
	}
	END_LOOP;
	POLYGON_LOOP (layer);
	{
	  Coord x1, y1, x2, y2, w, h, t;

	  if (! polygon_is_rectangle (polygon))
	    {
	      crooked = true;
	      continue;
	    }

	  w = polygon->Points[2].X - polygon->Points[0].X;
	  h = polygon->Points[1].Y - polygon->Points[0].Y;
	  t = (w < h) ? w : h;
	  x1 = polygon->Points[0].X + t/2;
	  y1 = polygon->Points[0].Y + t/2;
	  x2 = x1 + (w-t);
	  y2 = y1 + (h-t);

	  sprintf (num, "%d", pin_n++);
	  CreateNewPad (Element,
			x1, y1, x2, y2, t,
			2 * Settings.Keepaway,
			t + Settings.Keepaway,
			NULL, num,
			MakeFlags (SQUAREFLAG | onsolderflag));
	  MAYBE_WARN();
	  hasParts = true;
	}
	END_LOOP;
      }
      END_LOOP;
    }

  /* now add the silkscreen. NOTE: elements must have pads or pins too */
  LINE_LOOP (&Buffer->Data->SILKLAYER);
  {
    if (line->Number && !NAMEONPCB_NAME (Element))
      NAMEONPCB_NAME (Element) = strdup (line->Number);
    CreateNewLineInElement (Element, line->Point1.X,
			    line->Point1.Y, line->Point2.X,
			    line->Point2.Y, line->Thickness);
    hasParts = true;
  }
  END_LOOP;
  ARC_LOOP (&Buffer->Data->SILKLAYER);
  {
    CreateNewArcInElement (Element, arc->X, arc->Y, arc->Width,
			   arc->Height, arc->StartAngle, arc->Delta,
			   arc->Thickness);
    hasParts = true;
  }
  END_LOOP;
  if (!hasParts)
    {
      DestroyObject (PCB->Data, ELEMENT_TYPE, Element, Element, Element);
      Message (_("There was nothing to convert!\n"
		 "Elements must have some silk, pads or pins.\n"));
      return (false);
    }
  if (crooked)
     Message (_("There were polygons that can't be made into pins!\n"
                "So they were not included in the element\n"));
  Element->MarkX = Buffer->X;
  Element->MarkY = Buffer->Y;
  if (SWAP_IDENT)
    SET_FLAG (ONSOLDERFLAG, Element);
  SetElementBoundingBox (PCB->Data, Element, &PCB->Font);
  ClearBuffer (Buffer);
  MoveObjectToBuffer (Buffer->Data, PCB->Data, ELEMENT_TYPE, Element, Element,
		      Element);
  SetBufferBoundingBox (Buffer);
  return (true);
}
Esempio n. 8
0
/*---------------------------------------------------------------------------
 *
 * break buffer element into pieces
 */
bool
SmashBufferElement (BufferType *Buffer)
{
  ElementType *element;
  Cardinal group;
  LayerType *top_layer, *bottom_layer;

  if (Buffer->Data->ElementN != 1)
    {
      Message (_("Error!  Buffer doesn't contain a single element\n"));
      return (false);
    }
  /*
   * At this point the buffer should contain just a single element.
   * Now we detach the single element from the buffer and then clear the
   * buffer, ready to receive the smashed elements.  As a result of detaching
   * it the single element is orphaned from the buffer and thus will not be
   * free()'d by FreeDataMemory (called via ClearBuffer).  This leaves it
   * around for us to smash bits off it.  It then becomes our responsibility,
   * however, to free the single element when we're finished with it.
   */
  element = Buffer->Data->Element->data;
  Buffer->Data->Element = NULL;
  Buffer->Data->ElementN = 0;
  ClearBuffer (Buffer);
  ELEMENTLINE_LOOP (element);
  {
    CreateNewLineOnLayer (&Buffer->Data->SILKLAYER,
			  line->Point1.X, line->Point1.Y,
			  line->Point2.X, line->Point2.Y,
			  line->Thickness, 0, NoFlags ());
    if (line)
      line->Number = STRDUP (NAMEONPCB_NAME (element));
  }
  END_LOOP;
  ARC_LOOP (element);
  {
    CreateNewArcOnLayer (&Buffer->Data->SILKLAYER,
			 arc->X, arc->Y, arc->Width, arc->Height, arc->StartAngle,
			 arc->Delta, arc->Thickness, 0, NoFlags ());
  }
  END_LOOP;
  PIN_LOOP (element);
  {
    FlagType f = NoFlags ();
    AddFlags (f, VIAFLAG);
    if (TEST_FLAG (HOLEFLAG, pin))
      AddFlags (f, HOLEFLAG);

    CreateNewVia (Buffer->Data, pin->X, pin->Y,
		  pin->Thickness, pin->Clearance, pin->Mask,
		  pin->DrillingHole, pin->Number, f);
  }
  END_LOOP;
  group = GetLayerGroupNumberBySide (SWAP_IDENT ? BOTTOM_SIDE : TOP_SIDE);
  top_layer = &Buffer->Data->Layer[PCB->LayerGroups.Entries[group][0]];
  group = GetLayerGroupNumberBySide (SWAP_IDENT ? TOP_SIDE : BOTTOM_SIDE);
  bottom_layer = &Buffer->Data->Layer[PCB->LayerGroups.Entries[group][0]];
  PAD_LOOP (element);
  {
    LineType *line;
    line = CreateNewLineOnLayer (TEST_FLAG (ONSOLDERFLAG, pad) ? bottom_layer : top_layer,
				 pad->Point1.X, pad->Point1.Y,
				 pad->Point2.X, pad->Point2.Y,
				 pad->Thickness, pad->Clearance, NoFlags ());
    if (line)
      line->Number = STRDUP (pad->Number);
  }
  END_LOOP;
  FreeElementMemory (element);
  g_slice_free (ElementType, element);
  return (true);
}
Esempio n. 9
0
/* ---------------------------------------------------------------------------
 * flip components/tracks from one side to the other
 */
static void
SwapBuffer (BufferType *Buffer)
{
  int j, k;
  Cardinal top_group, bottom_group;
  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[bottom_silk_layer];
  Buffer->Data->Layer[bottom_silk_layer] =
    Buffer->Data->Layer[top_silk_layer];
  Buffer->Data->Layer[top_silk_layer] = swap;

  /* swap layer groups when balanced */
  top_group = GetLayerGroupNumberBySide (TOP_SIDE);
  bottom_group = GetLayerGroupNumberBySide (BOTTOM_SIDE);
  if (PCB->LayerGroups.Number[top_group] == PCB->LayerGroups.Number[bottom_group])
    {
      for (j = k = 0; j < PCB->LayerGroups.Number[bottom_group]; j++)
	{
	  int t1, t2;
	  Cardinal top_number = PCB->LayerGroups.Entries[top_group][k];
	  Cardinal bottom_number = PCB->LayerGroups.Entries[bottom_group][j];

	  if (bottom_number >= max_copper_layer)
	    continue;
	  swap = Buffer->Data->Layer[bottom_number];

	  while (top_number >= max_copper_layer)
	    {
	      k++;
	      top_number = PCB->LayerGroups.Entries[top_group][k];
	    }
	  Buffer->Data->Layer[bottom_number] = Buffer->Data->Layer[top_number];
	  Buffer->Data->Layer[top_number] = swap;
	  k++;
	  /* move the thermal flags with the layers */
	  ALLPIN_LOOP (Buffer->Data);
	  {
	    t1 = TEST_THERM (bottom_number, pin);
	    t2 = TEST_THERM (top_number, pin);
	    ASSIGN_THERM (bottom_number, t2, pin);
	    ASSIGN_THERM (top_number, t1, pin);
	  }
	  ENDALL_LOOP;
	  VIA_LOOP (Buffer->Data);
	  {
	    t1 = TEST_THERM (bottom_number, via);
	    t2 = TEST_THERM (top_number, via);
	    ASSIGN_THERM (bottom_number, t2, via);
	    ASSIGN_THERM (top_number, t1, via);
	  }
	  END_LOOP;
	}
    }
  SetBufferBoundingBox (Buffer);
  SetCrosshairRangeToBuffer ();
}
Esempio n. 10
0
/*!
 * \brief Recalculates the passed coordinates to fit the current grid
 * setting.
 */
void
FitCrosshairIntoGrid (Coord X, Coord Y)
{
  Coord nearest_grid_x, nearest_grid_y;
  void *ptr1, *ptr2, *ptr3;
  struct snap_data snap_data;
  int ans;

  Crosshair.X = CLAMP (X, Crosshair.MinX, Crosshair.MaxX);
  Crosshair.Y = CLAMP (Y, Crosshair.MinY, Crosshair.MaxY);

  if (PCB->RatDraw)
    {
      nearest_grid_x = -MIL_TO_COORD (6);
      nearest_grid_y = -MIL_TO_COORD (6);
    }
  else
    {
      nearest_grid_x = GridFit (Crosshair.X, PCB->Grid, PCB->GridOffsetX);
      nearest_grid_y = GridFit (Crosshair.Y, PCB->Grid, PCB->GridOffsetY);

      if (Marked.status && TEST_FLAG (ORTHOMOVEFLAG, PCB))
	{
	  Coord dx = Crosshair.X - Marked.X;
	  Coord dy = Crosshair.Y - Marked.Y;
	  if (ABS (dx) > ABS (dy))
	    nearest_grid_y = Marked.Y;
	  else
	    nearest_grid_x = Marked.X;
	}

    }

  snap_data.crosshair = &Crosshair;
  snap_data.nearest_sq_dist =
    crosshair_sq_dist (&Crosshair, nearest_grid_x, nearest_grid_y);
  snap_data.nearest_is_grid = true;
  snap_data.x = nearest_grid_x;
  snap_data.y = nearest_grid_y;

  ans = NO_TYPE;
  if (!PCB->RatDraw)
    ans = SearchObjectByLocation (ELEMENT_TYPE, &ptr1, &ptr2, &ptr3,
                                  Crosshair.X, Crosshair.Y, PCB->Grid / 2);

  if (ans & ELEMENT_TYPE)
    {
      ElementType *el = (ElementType *) ptr1;
      check_snap_object (&snap_data, el->MarkX, el->MarkY, false);
    }

  ans = NO_TYPE;
  if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB))
    ans = SearchObjectByLocation (PAD_TYPE, &ptr1, &ptr2, &ptr3,
                                  Crosshair.X, Crosshair.Y, PCB->Grid / 2);

  /* Avoid self-snapping when moving */
  if (ans != NO_TYPE &&
      Settings.Mode == MOVE_MODE &&
      Crosshair.AttachedObject.Type == ELEMENT_TYPE &&
      ptr1 == Crosshair.AttachedObject.Ptr1)
    ans = NO_TYPE;

  if (ans != NO_TYPE &&
      ( Settings.Mode == LINE_MODE ||
       (Settings.Mode == MOVE_MODE &&
        Crosshair.AttachedObject.Type == LINEPOINT_TYPE)))
    {
      PadType *pad = (PadType *) ptr2;
      LayerType *desired_layer;
      Cardinal desired_group;
      Cardinal bottom_group, top_group;
      int found_our_layer = false;

      desired_layer = CURRENT;
      if (Settings.Mode == MOVE_MODE &&
          Crosshair.AttachedObject.Type == LINEPOINT_TYPE)
        {
          desired_layer = (LayerType *)Crosshair.AttachedObject.Ptr1;
        }

      /* find layer groups of the top and bottom sides */
      top_group = GetLayerGroupNumberBySide (TOP_SIDE);
      bottom_group = GetLayerGroupNumberBySide (BOTTOM_SIDE);
      desired_group = TEST_FLAG (ONSOLDERFLAG, pad) ? bottom_group : top_group;

      GROUP_LOOP (PCB->Data, desired_group);
      {
        if (layer == desired_layer)
          {
            found_our_layer = true;
            break;
          }
      }
      END_LOOP;

      if (found_our_layer == false)
        ans = NO_TYPE;
    }

  if (ans != NO_TYPE)
    {
      PadType *pad = (PadType *)ptr2;
      check_snap_object (&snap_data, pad->Point1.X + (pad->Point2.X - pad->Point1.X) / 2,
                                     pad->Point1.Y + (pad->Point2.Y - pad->Point1.Y) / 2,
                         true);
    }

  ans = NO_TYPE;
  if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB))
    ans = SearchObjectByLocation (PIN_TYPE, &ptr1, &ptr2, &ptr3,
                                  Crosshair.X, Crosshair.Y, PCB->Grid / 2);

  /* Avoid self-snapping when moving */
  if (ans != NO_TYPE &&
      Settings.Mode == MOVE_MODE &&
      Crosshair.AttachedObject.Type == ELEMENT_TYPE &&
      ptr1 == Crosshair.AttachedObject.Ptr1)
    ans = NO_TYPE;

  if (ans != NO_TYPE)
    {
      PinType *pin = (PinType *)ptr2;
      check_snap_object (&snap_data, pin->X, pin->Y, true);
    }

  ans = NO_TYPE;
  if (TEST_FLAG (SNAPPINFLAG, PCB))
    ans = SearchObjectByLocation (VIA_TYPE, &ptr1, &ptr2, &ptr3,
                                  Crosshair.X, Crosshair.Y, PCB->Grid / 2);

  /* Avoid snapping vias to any other vias */
  if (Settings.Mode == MOVE_MODE &&
      Crosshair.AttachedObject.Type == VIA_TYPE &&
      (ans & PIN_TYPES))
    ans = NO_TYPE;

  if (ans != NO_TYPE)
    {
      PinType *pin = (PinType *)ptr2;
      check_snap_object (&snap_data, pin->X, pin->Y, true);
    }

  ans = NO_TYPE;
  if (TEST_FLAG (SNAPPINFLAG, PCB))
    ans = SearchObjectByLocation (LINEPOINT_TYPE | ARCPOINT_TYPE,
                                  &ptr1, &ptr2, &ptr3,
                                  Crosshair.X, Crosshair.Y, PCB->Grid / 2);

  if (ans != NO_TYPE)
    {
      PointType *pnt = (PointType *)ptr3;
      check_snap_object (&snap_data, pnt->X, pnt->Y, true);
    }

  check_snap_offgrid_line (&snap_data, nearest_grid_x, nearest_grid_y);

  ans = NO_TYPE;
  if (TEST_FLAG (SNAPPINFLAG, PCB))
    ans = SearchObjectByLocation (POLYGONPOINT_TYPE, &ptr1, &ptr2, &ptr3,
                                  Crosshair.X, Crosshair.Y, PCB->Grid / 2);

  if (ans != NO_TYPE)
    {
      PointType *pnt = (PointType *)ptr3;
      check_snap_object (&snap_data, pnt->X, pnt->Y, true);
    }

  if (snap_data.x >= 0 && snap_data.y >= 0)
    {
      Crosshair.X = snap_data.x;
      Crosshair.Y = snap_data.y;
    }

  if (Settings.Mode == ARROW_MODE)
    {
      ans = SearchObjectByLocation (LINEPOINT_TYPE | ARCPOINT_TYPE,
                                    &ptr1, &ptr2, &ptr3,
                                    Crosshair.X, Crosshair.Y, PCB->Grid / 2);
      if (ans == NO_TYPE)
        hid_action("PointCursor");
      else if (!TEST_FLAG(SELECTEDFLAG, (LineType *)ptr2))
        hid_actionl("PointCursor","True", NULL);
    }

  if (Settings.Mode == LINE_MODE
      && Crosshair.AttachedLine.State != STATE_FIRST
      && TEST_FLAG (AUTODRCFLAG, PCB))
    EnforceLineDRC ();

  gui->set_crosshair (Crosshair.X, Crosshair.Y, HID_SC_DO_NOTHING);
}