Exemple #1
0
void
log_element(ElementType *e)
{
  base_log("Element\n");
  base_log("Description: %s\n", DESCRIPTION_NAME(e));
  base_log("Name on PCB: %s\n", NAMEONPCB_NAME(e));
  base_log("Value: %s\n", VALUE_NAME(e));
  base_log("Flags: %04x\n", FLAG_VALUE(e->Flags));
  base_log("MarkX, MarkY: %d, %d\n", e->MarkX, e->MarkY);
  base_log("PinN: %d\n", e->PinN);
  base_log("PadN: %d\n", e->PadN);
  base_log("LineN: %d\n", e->LineN);
  base_log("ArcN: %d\n", e->ArcN);
  base_log("Attributes number: %d\n", e->Attributes.Number);

  int i = 0;
  PAD_LOOP(e);
  {
    base_log("Pad %d\n", i++);
    log_pad(pad);
  }
  END_LOOP;

  i = 0;
  PIN_LOOP(e);
  {
    base_log("Pin %d\n", i++);
    log_pin(pin);
  }
  END_LOOP;
}
static int
replace_footprints(ElementTypePtr new_element)
{
  int replaced = 0;
  int i = 0;

  ELEMENT_LOOP (PCB->Data);
  {
    if (match_mode != MATCH_MODE_AUTO
        || strcmp(DESCRIPTION_NAME(new_element),
                  DESCRIPTION_NAME(element)) == 0) {
      Boolean matched = False;

      switch (style) {
      case STYLE_ALL:
        matched = True;
        break;
      case STYLE_SELECTED:
        matched = TEST_FLAG(SELECTEDFLAG, element);
        break;
      case STYLE_NAMED:
        for (i = 0; i < global_argc; i++) {
          if (NAMEONPCB_NAME(element)
              && strcasecmp(NAMEONPCB_NAME(element), global_argv[i]) == 0) {
            matched = True;
            break;
          }
        }
        break;
      }
      if (matched) {
        if (TEST_FLAG (LOCKFLAG, element)) {
          base_log("Skipping \"%s\".  Element locked.\n",
                   NAMEONPCB_NAME(element));
        } else {
          debug_log("Considering \"%s\".\n", NAMEONPCB_NAME(element));
          if (replace_one_footprint(element, new_element)) {
            base_log("Replaced \"%s\".\n", NAMEONPCB_NAME(element));
            replaced++;
          }
        }
      }
    }
  }
  END_LOOP;
  return replaced;
}
Exemple #3
0
void
ghid_pinout_window_show (GHidPort * out, ElementType * element)
{
    GtkWidget *button, *vbox, *hbox, *preview, *top_window;
    gchar *title;
    int width, height;

    if (!element)
        return;
    title = g_strdup_printf ("%s [%s,%s]",
                             UNKNOWN (DESCRIPTION_NAME (element)),
                             UNKNOWN (NAMEONPCB_NAME (element)),
                             UNKNOWN (VALUE_NAME (element)));

    top_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title (GTK_WINDOW (top_window), title);
    g_free (title);
    gtk_window_set_wmclass (GTK_WINDOW (top_window), "PCB_Pinout", "PCB");
    gtk_container_set_border_width (GTK_CONTAINER (top_window), 4);

    vbox = gtk_vbox_new (FALSE, 0);
    gtk_container_add (GTK_CONTAINER (top_window), vbox);


    preview = ghid_pinout_preview_new (element);
    gtk_box_pack_start (GTK_BOX (vbox), preview, TRUE, TRUE, 0);

    ghid_pinout_preview_get_natural_size (GHID_PINOUT_PREVIEW (preview),
                                          &width, &height);

    gtk_window_set_default_size (GTK_WINDOW (top_window),
                                 width + 50, height + 50);

    hbox = gtk_hbutton_box_new ();
    gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END);
    gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
    button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (pinout_close_cb), top_window);
    gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);

    gtk_widget_realize (top_window);
    if (Settings.AutoPlace)
        gtk_window_move (GTK_WINDOW (top_window), 10, 10);
    gtk_widget_show_all (top_window);
}
Exemple #4
0
/* ---------------------------------------------------------------------------
 * writes element data
 */
static void
WriteElementData (FILE * FP, DataType *Data)
{
  GList *n, *p;
  for (n = Data->Element; n != NULL; n = g_list_next (n))
    {
      ElementType *element = n->data;

      /* only non empty elements */
      if (!element->LineN && !element->PinN && !element->ArcN
	  && !element->PadN)
	continue;
      /* the coordinates and text-flags are the same for
       * both names of an element
       */
      fprintf (FP, "\nElement[%s ", F2S (element, ELEMENT_TYPE));
      PrintQuotedString (FP, (char *)EMPTY (DESCRIPTION_NAME (element)));
      fputc (' ', FP);
      PrintQuotedString (FP, (char *)EMPTY (NAMEONPCB_NAME (element)));
      fputc (' ', FP);
      PrintQuotedString (FP, (char *)EMPTY (VALUE_NAME (element)));
      pcb_fprintf (FP, " %mr %mr %mr %mr %d %d %s]\n(\n",
                   element->MarkX, element->MarkY,
                   DESCRIPTION_TEXT (element).X - element->MarkX,
                   DESCRIPTION_TEXT (element).Y - element->MarkY,
                   DESCRIPTION_TEXT (element).Direction,
                   DESCRIPTION_TEXT (element).Scale,
                   F2S (&(DESCRIPTION_TEXT (element)), ELEMENTNAME_TYPE));
      WriteAttributeList (FP, &element->Attributes, "\t");
      for (p = element->Pin; p != NULL; p = g_list_next (p))
	{
	  PinType *pin = p->data;
          pcb_fprintf (FP, "\tPin[%mr %mr %mr %mr %mr %mr ",
                       pin->X - element->MarkX,
                       pin->Y - element->MarkY,
                       pin->Thickness, pin->Clearance,
                       pin->Mask, pin->DrillingHole);
	  PrintQuotedString (FP, (char *)EMPTY (pin->Name));
	  fprintf (FP, " ");
	  PrintQuotedString (FP, (char *)EMPTY (pin->Number));
	  fprintf (FP, " %s]\n", F2S (pin, PIN_TYPE));
	}
      for (p = element->Pad; p != NULL; p = g_list_next (p))
	{
	  PadType *pad = p->data;
          pcb_fprintf (FP, "\tPad[%mr %mr %mr %mr %mr %mr %mr ",
                       pad->Point1.X - element->MarkX,
                       pad->Point1.Y - element->MarkY,
                       pad->Point2.X - element->MarkX,
                       pad->Point2.Y - element->MarkY,
                       pad->Thickness, pad->Clearance, pad->Mask);
	  PrintQuotedString (FP, (char *)EMPTY (pad->Name));
	  fprintf (FP, " ");
	  PrintQuotedString (FP, (char *)EMPTY (pad->Number));
	  fprintf (FP, " %s]\n", F2S (pad, PAD_TYPE));
	}
      for (p = element->Line; p != NULL; p = g_list_next (p))
	{
	  LineType *line = p->data;
          pcb_fprintf (FP, "\tElementLine [%mr %mr %mr %mr %mr]\n",
                       line->Point1.X - element->MarkX,
                       line->Point1.Y - element->MarkY,
                       line->Point2.X - element->MarkX,
                       line->Point2.Y - element->MarkY,
                       line->Thickness);
	}
      for (p = element->Arc; p != NULL; p = g_list_next (p))
	{
	  ArcType *arc = p->data;
          pcb_fprintf (FP, "\tElementArc [%mr %mr %mr %mr %ma %ma %mr]\n",
                       arc->X - element->MarkX,
                       arc->Y - element->MarkY,
                       arc->Width, arc->Height,
                       arc->StartAngle, arc->Delta,
                       arc->Thickness);
	}
      fputs ("\n\t)\n", FP);
    }
}
Exemple #5
0
/* ---------------------------------------------------------------------------
 * writes element data
 */
static void
WriteElementData (FILE * FP, DataTypePtr Data)
{
  int n, p;
  for (n = 0; n < Data->ElementN; n++)
    {
      ElementTypePtr element = &Data->Element[n];
      /* only non empty elements */
      if (!element->LineN && !element->PinN && !element->ArcN
	  && !element->PadN)
	continue;
      /* the coordinates and text-flags are the same for
       * both names of an element
       */
      fprintf (FP, "\nElement[%s ", F2S (element, ELEMENT_TYPE));
      PrintQuotedString (FP, (char *)EMPTY (DESCRIPTION_NAME (element)));
      fputc (' ', FP);
      PrintQuotedString (FP, (char *)EMPTY (NAMEONPCB_NAME (element)));
      fputc (' ', FP);
      PrintQuotedString (FP, (char *)EMPTY (VALUE_NAME (element)));
      fprintf (FP, " %i %i %i %i %i %i %s]\n(\n",
	       (int) element->MarkX, (int) element->MarkY,
	       (int) (DESCRIPTION_TEXT (element).X -
		      element->MarkX),
	       (int) (DESCRIPTION_TEXT (element).Y -
		      element->MarkY),
	       (int) DESCRIPTION_TEXT (element).Direction,
	       (int) DESCRIPTION_TEXT (element).Scale,
	       F2S (&(DESCRIPTION_TEXT (element)), ELEMENTNAME_TYPE));
      WriteAttributeList (FP, &element->Attributes, "\t");
      for (p = 0; p < element->PinN; p++)
	{
	  PinTypePtr pin = &element->Pin[p];
	  fprintf (FP, "\tPin[%i %i %i %i %i %i ",
		   (int) (pin->X - element->MarkX),
		   (int) (pin->Y - element->MarkY),
		   (int) pin->Thickness, (int) pin->Clearance,
		   (int) pin->Mask, (int) pin->DrillingHole);
	  PrintQuotedString (FP, (char *)EMPTY (pin->Name));
	  fprintf (FP, " ");
	  PrintQuotedString (FP, (char *)EMPTY (pin->Number));
	  fprintf (FP, " %s]\n", F2S (pin, PIN_TYPE));
	}
      for (p = 0; p < element->PadN; p++)
	{
	  PadTypePtr pad = &element->Pad[p];
	  fprintf (FP, "\tPad[%i %i %i %i %i %i %i ",
		   (int) (pad->Point1.X - element->MarkX),
		   (int) (pad->Point1.Y - element->MarkY),
		   (int) (pad->Point2.X - element->MarkX),
		   (int) (pad->Point2.Y - element->MarkY),
		   (int) pad->Thickness, (int) pad->Clearance,
		   (int) pad->Mask);
	  PrintQuotedString (FP, (char *)EMPTY (pad->Name));
	  fprintf (FP, " ");
	  PrintQuotedString (FP, (char *)EMPTY (pad->Number));
	  fprintf (FP, " %s]\n", F2S (pad, PAD_TYPE));
	}
      for (p = 0; p < element->LineN; p++)
	{
	  LineTypePtr line = &element->Line[p];
	  fprintf (FP,
		   "\tElementLine [%i %i %i %i %i]\n",
		   (int) (line->Point1.X -
			  element->MarkX),
		   (int) (line->Point1.Y -
			  element->MarkY),
		   (int) (line->Point2.X -
			  element->MarkX),
		   (int) (line->Point2.Y -
			  element->MarkY), (int) line->Thickness);
	}
      for (p = 0; p < element->ArcN; p++)
	{
	  ArcTypePtr arc = &element->Arc[p];
	  fprintf (FP,
		   "\tElementArc [%i %i %i %i %i %i %i]\n",
		   (int) (arc->X - element->MarkX),
		   (int) (arc->Y - element->MarkY),
		   (int) arc->Width, (int) arc->Height,
		   (int) arc->StartAngle, (int) arc->Delta,
		   (int) arc->Thickness);
	}
      fputs ("\n\t)\n", FP);
    }
}
Exemple #6
0
/* ---------------------------------------------------------------------------
 * copies data from one element to another and creates the destination 
 * if necessary
 */
ElementType *
CopyElementLowLevel (DataType *Data, ElementType *Src,
                     bool uniqueName, Coord dx, Coord dy, int mask_flags)
{
  int i;
  ElementType *Dest;

  /* both coordinates and flags are the same */
  Dest = CreateNewElement (Data, &PCB->Font,
			   MaskFlags (Src->Flags, mask_flags),
			   DESCRIPTION_NAME (Src), NAMEONPCB_NAME (Src),
			   VALUE_NAME (Src), DESCRIPTION_TEXT (Src).X + dx,
			   DESCRIPTION_TEXT (Src).Y + dy,
			   DESCRIPTION_TEXT (Src).Direction,
			   DESCRIPTION_TEXT (Src).Scale,
			   MaskFlags (DESCRIPTION_TEXT (Src).Flags,
				      mask_flags), uniqueName);

  /* abort on error */
  if (!Dest)
    return (Dest);

  ELEMENTLINE_LOOP (Src);
  {
    CreateNewLineInElement (Dest, line->Point1.X + dx,
			    line->Point1.Y + dy, line->Point2.X + dx,
			    line->Point2.Y + dy, line->Thickness);
  }
  END_LOOP;
  PIN_LOOP (Src);
  {
    CreateNewPin (Dest, pin->X + dx, pin->Y + dy, pin->Thickness,
		  pin->Clearance, pin->Mask, pin->DrillingHole,
		  pin->Name, pin->Number, MaskFlags (pin->Flags, mask_flags));
  }
  END_LOOP;
  PAD_LOOP (Src);
  {
    CreateNewPad (Dest, pad->Point1.X + dx, pad->Point1.Y + dy,
		  pad->Point2.X + dx, pad->Point2.Y + dy, pad->Thickness,
		  pad->Clearance, pad->Mask, pad->Name, pad->Number,
		  MaskFlags (pad->Flags, mask_flags));
  }
  END_LOOP;
  ARC_LOOP (Src);
  {
    CreateNewArcInElement (Dest, arc->X + dx, arc->Y + dy, arc->Width,
			   arc->Height, arc->StartAngle, arc->Delta,
			   arc->Thickness);
  }
  END_LOOP;

  for (i=0; i<Src->Attributes.Number; i++)
    CreateNewAttribute (& Dest->Attributes,
			Src->Attributes.List[i].name,
			Src->Attributes.List[i].value);

  Dest->MarkX = Src->MarkX + dx;
  Dest->MarkY = Src->MarkY + dy;

  SetElementBoundingBox (Data, Dest, &PCB->Font);
  return (Dest);
}
Exemple #7
0
static int
PrintBOM (void)
{
  char utcTime[64];
  Coord x, y;
  double theta = 0.0;
  double sumx, sumy;
  int pinfound[MAXREFPINS];
  double pinx[MAXREFPINS];
  double piny[MAXREFPINS];
  double pinangle[MAXREFPINS];
  double padcentrex, padcentrey;
  double centroidx, centroidy;
  double pin1x, pin1y;
  int pin_cnt;
  int found_any_not_at_centroid;
  int found_any;
  time_t currenttime;
  FILE *fp;
  BomList *bom = NULL;
  char *name, *descr, *value,*fixed_rotation;
  int rpindex;

  fp = fopen (xy_filename, "w");
  if (!fp)
    {
      gui->log ("Cannot open file %s for writing\n", xy_filename);
      return 1;
    }

  /* Create a portable timestamp. */
  currenttime = time (NULL);
  {
    /* avoid gcc complaints */
    const char *fmt = "%c UTC";
    strftime (utcTime, sizeof (utcTime), fmt, gmtime (&currenttime));
  }
  fprintf (fp, "# PcbXY Version 1.0\n");
  fprintf (fp, "# Date: %s\n", utcTime);
  fprintf (fp, "# Author: %s\n", pcb_author ());
  fprintf (fp, "# Title: %s - PCB X-Y\n", UNKNOWN (PCB->Name));
  fprintf (fp, "# RefDes, Description, Value, X, Y, rotation, top/bottom\n");
  /* don't use localized xy_unit->in_suffix here since */
  /* the line itself is not localized and not for GUI  */
  fprintf (fp, "# X,Y in %s.  rotation in degrees.\n", xy_unit->suffix);
  fprintf (fp, "# --------------------------------------------\n");

  /*
   * For each element we calculate the centroid of the footprint.
   * In addition, we need to extract some notion of rotation.
   * While here generate the BOM list
   */

  ELEMENT_LOOP (PCB->Data);
  {

    /* Initialize our pin count and our totals for finding the centroid. */
    pin_cnt = 0;
    sumx = 0.0;
    sumy = 0.0;
    for (rpindex = 0; rpindex < MAXREFPINS; rpindex++)
      pinfound[rpindex] = 0;

    /* Insert this component into the bill of materials list. */
    bom = bom_insert ((char *)UNKNOWN (NAMEONPCB_NAME (element)),
                      (char *)UNKNOWN (DESCRIPTION_NAME (element)),
                      (char *)UNKNOWN (VALUE_NAME (element)), bom);


    /*
     * Iterate over the pins and pads keeping a running count of how
     * many pins/pads total and the sum of x and y coordinates
     *
     * While we're at it, store the location of pin/pad #1 and #2 if
     * we can find them.
     */

    PIN_LOOP (element);
    {
      sumx += (double) pin->X;
      sumy += (double) pin->Y;
      pin_cnt++;

      for (rpindex = 0; reference_pin_names[rpindex]; rpindex++)
        {
          if (NSTRCMP (pin->Number, reference_pin_names[rpindex]) == 0)
            {
                pinx[rpindex] = (double) pin->X;
                piny[rpindex] = (double) pin->Y;
                pinangle[rpindex] = 0.0; /* pins have no notion of angle */
                pinfound[rpindex] = 1;
            }
        }
    }
    END_LOOP;

    PAD_LOOP (element);
    {
      sumx += (pad->Point1.X + pad->Point2.X) / 2.0;
      sumy += (pad->Point1.Y + pad->Point2.Y) / 2.0;
      pin_cnt++;

      for (rpindex = 0; reference_pin_names[rpindex]; rpindex++)
        {
          if (NSTRCMP (pad->Number, reference_pin_names[rpindex]) == 0)
            {
              padcentrex = (double) (pad->Point1.X + pad->Point2.X) / 2.0;
              padcentrey = (double) (pad->Point1.Y + pad->Point2.Y) / 2.0;
              pinx[rpindex] = padcentrex;
              piny[rpindex] = padcentrey;
              /*
               * NOTE: We swap the Y points because in PCB, the Y-axis
               * is inverted.  Increasing Y moves down.  We want to deal
               * in the usual increasing Y moves up coordinates though.
               */
              pinangle[rpindex] = (180.0 / M_PI) * atan2 (pad->Point1.Y - pad->Point2.Y,
                pad->Point2.X - pad->Point1.X);
              pinfound[rpindex]=1;
            }
        }
    }
    END_LOOP;

    if (pin_cnt > 0)
      {
	centroidx = sumx / (double) pin_cnt;
	centroidy = sumy / (double) pin_cnt;
	      
	if (NSTRCMP( AttributeGetFromList (&element->Attributes,"xy-centre"), "origin") == 0 )
	  {
            x = element->MarkX;
            y = element->MarkY;
	  }
	else
	  {
            x = centroidx;
            y = centroidy;
	  }
	
	fixed_rotation = AttributeGetFromList (&element->Attributes, "xy-fixed-rotation");
	if (fixed_rotation)
	  {	
            /* The user specified a fixed rotation */
            theta = atof (fixed_rotation);
            found_any_not_at_centroid = 1;
            found_any = 1;
	  } 
	else
	  {
            /* Find first reference pin not at the  centroid  */
            found_any_not_at_centroid = 0;
            found_any = 0;
            theta = 0.0;
            for (rpindex = 0;
                 reference_pin_names[rpindex] && !found_any_not_at_centroid;
                 rpindex++)
              {
		if (pinfound[rpindex])
		  {
                    found_any = 1;

                    /* Recenter pin "#1" onto the axis which cross at the part
                       centroid */
                    pin1x = pinx[rpindex] - x;
                    pin1y = piny[rpindex] - y;

                    /* flip x, to reverse rotation for elements on back */
                    if (FRONT (element) != 1)
                        pin1x = -pin1x;

                    /* if only 1 pin, use pin 1's angle */
                    if (pin_cnt == 1)
                      {
                        theta = pinangle[rpindex];
                        found_any_not_at_centroid = 1;
                      }
                    else if ((pin1x != 0.0) || (pin1y != 0.0))
                      {
                        theta = xyToAngle (pin1x, pin1y, pin_cnt > 2);
                        found_any_not_at_centroid = 1;
                      }
                  }
              }

            if (!found_any)
              {
                Message
                  ("PrintBOM(): unable to figure out angle because I could\n"
                   "     not find a suitable reference pin of element %s\n"
                   "     Setting to %g degrees\n",
                   UNKNOWN (NAMEONPCB_NAME (element)), theta);
              }
            else if (!found_any_not_at_centroid)
              {
                Message
                      ("PrintBOM(): unable to figure out angle of element\n"
                       "     %s because the reference pin(s) are at the centroid of the part.\n"
                       "     Setting to %g degrees\n",
                       UNKNOWN (NAMEONPCB_NAME (element)), theta);
	      }
          }
	name = CleanBOMString ((char *)UNKNOWN (NAMEONPCB_NAME (element)));
	descr = CleanBOMString ((char *)UNKNOWN (DESCRIPTION_NAME (element)));
	value = CleanBOMString ((char *)UNKNOWN (VALUE_NAME (element)));

 	y = PCB->MaxHeight - y;
	pcb_fprintf (fp, "%m+%s,\"%s\",\"%s\",%.2mS,%.2mS,%g,%s\n",
		     xy_unit->allow, name, descr, value, x, y,
		     theta, FRONT (element) == 1 ? "top" : "bottom");
	free (name);
	free (descr);
	free (value);
      }
  }
  END_LOOP;

  fclose (fp);

  /* Now print out a Bill of Materials file */

  fp = fopen (bom_filename, "w");
  if (!fp)
    {
      gui->log ("Cannot open file %s for writing\n", bom_filename);
      print_and_free (NULL, bom);
      return 1;
    }

  fprintf (fp, "# PcbBOM Version 1.0\n");
  fprintf (fp, "# Date: %s\n", utcTime);
  fprintf (fp, "# Author: %s\n", pcb_author ());
  fprintf (fp, "# Title: %s - PCB BOM\n", UNKNOWN (PCB->Name));
  fprintf (fp, "# Quantity, Description, Value, RefDes\n");
  fprintf (fp, "# --------------------------------------------\n");

  print_and_free (fp, bom);

  fclose (fp);

  return (0);
}
Exemple #8
0
bool
vendorIsElementMappable (ElementType *element)
{
  int i;
  int noskip;

  if (vendorMapEnable == false)
    return false;

  noskip = 1;
  for (i = 0; i < n_refdes; i++)
    {
      if ((NSTRCMP (UNKNOWN (NAMEONPCB_NAME (element)), ignore_refdes[i]) ==
	   0)
	  || rematch (ignore_refdes[i], UNKNOWN (NAMEONPCB_NAME (element))))
	{
	  Message (_
		   ("Vendor mapping skipped because refdes = %s matches %s\n"),
		   UNKNOWN (NAMEONPCB_NAME (element)), ignore_refdes[i]);
	  noskip = 0;
	}
    }
  if (noskip)
    for (i = 0; i < n_value; i++)
      {
	if ((NSTRCMP (UNKNOWN (VALUE_NAME (element)), ignore_value[i]) == 0)
	    || rematch (ignore_value[i], UNKNOWN (VALUE_NAME (element))))
	  {
	    Message (_
		     ("Vendor mapping skipped because value = %s matches %s\n"),
		     UNKNOWN (VALUE_NAME (element)), ignore_value[i]);
	    noskip = 0;
	  }
      }

  if (noskip)
    for (i = 0; i < n_descr; i++)
      {
	if ((NSTRCMP (UNKNOWN (DESCRIPTION_NAME (element)), ignore_descr[i])
	     == 0)
	    || rematch (ignore_descr[i],
			UNKNOWN (DESCRIPTION_NAME (element))))
	  {
	    Message (_
		     ("Vendor mapping skipped because descr = %s matches %s\n"),
		     UNKNOWN (DESCRIPTION_NAME (element)), ignore_descr[i]);
	    noskip = 0;
	  }
      }

  if (noskip && TEST_FLAG (LOCKFLAG, element))
    {
      Message (_("Vendor mapping skipped because element %s is locked\n"),
	       UNKNOWN (NAMEONPCB_NAME (element)));
      noskip = 0;
    }

  if (noskip)
    return true;
  else
    return false;
}
Exemple #9
0
static void
apply_vendor_map (void)
{
  int i;
  int changed, tot;
  bool state;

  state = vendorMapEnable;

  /* enable mapping */
  vendorMapEnable = true;

  /* reset our counts */
  changed = 0;
  tot = 0;

  /* If we have loaded vendor drills, then apply them to the design */
  if (n_vendor_drills > 0)
    {

      /* first all the vias */
      VIA_LOOP (PCB->Data);
      {
	tot++;
	if (via->DrillingHole != vendorDrillMap (via->DrillingHole))
	  {
	    /* only change unlocked vias */
	    if (!TEST_FLAG (LOCKFLAG, via))
	      {
		if (ChangeObject2ndSize (VIA_TYPE, via, NULL, NULL,
					 vendorDrillMap (via->DrillingHole),
					 true, false))
		  changed++;
		else
		  {
		    Message (_
			     ("Via at %.2f, %.2f not changed.  Possible reasons:\n"
			      "\t- pad size too small\n"
			      "\t- new size would be too large or too small\n"),
			     0.01 * via->X, 0.01 * via->Y);
		  }
	      }
	    else
	      {
		Message (_("Locked via at %.2f, %.2f not changed.\n"),
			 0.01 * via->X, 0.01 * via->Y);
	      }
	  }
      }
      END_LOOP;

      /* and now the pins */
      ELEMENT_LOOP (PCB->Data);
      {
	/*
	 * first figure out if this element should be skipped for some
	 * reason
	 */
	if (vendorIsElementMappable (element))
	  {
	    /* the element is ok to modify, so iterate over its pins */
	    PIN_LOOP (element);
	    {
	      tot++;
	      if (pin->DrillingHole != vendorDrillMap (pin->DrillingHole))
		{
		  if (!TEST_FLAG (LOCKFLAG, pin))
		    {
		      if (ChangeObject2ndSize (PIN_TYPE, element, pin, NULL,
					       vendorDrillMap (pin->
							       DrillingHole),
					       true, false))
			changed++;
		      else
			{
			  Message (_
				   ("Pin %s (%s) at %.2f, %.2f (element %s, %s, %s) not changed.\n"
				    "\tPossible reasons:\n"
				    "\t- pad size too small\n"
				    "\t- new size would be too large or too small\n"),
				   UNKNOWN (pin->Number), UNKNOWN (pin->Name),
				   0.01 * pin->X, 0.01 * pin->Y,
				   UNKNOWN (NAMEONPCB_NAME (element)),
				   UNKNOWN (VALUE_NAME (element)),
				   UNKNOWN (DESCRIPTION_NAME (element)));
			}
		    }
		  else
		    {
		      Message (_
			       ("Locked pin at %-6.2f, %-6.2f not changed.\n"),
			       0.01 * pin->X, 0.01 * pin->Y);
		    }
		}
	    }
	    END_LOOP;
	  }
      }
      END_LOOP;

      Message (_("Updated %d drill sizes out of %d total\n"), changed, tot);

      /* Update the current Via */
      if (Settings.ViaDrillingHole !=
	  vendorDrillMap (Settings.ViaDrillingHole))
	{
	  changed++;
	  Settings.ViaDrillingHole =
	    vendorDrillMap (Settings.ViaDrillingHole);
	  Message (_("Adjusted active via hole size to be %6.2f mils\n"),
		   0.01 * Settings.ViaDrillingHole);
	}

      /* and update the vias for the various routing styles */
      for (i = 0; i < NUM_STYLES; i++)
	{
	  if (PCB->RouteStyle[i].Hole !=
	      vendorDrillMap (PCB->RouteStyle[i].Hole))
	    {
	      changed++;
	      PCB->RouteStyle[i].Hole =
		vendorDrillMap (PCB->RouteStyle[i].Hole);
	      Message (_
		       ("Adjusted %s routing style via hole size to be %6.2f mils\n"),
		       PCB->RouteStyle[i].Name,
		       0.01 * PCB->RouteStyle[i].Hole);
	      if (PCB->RouteStyle[i].Diameter <
		  PCB->RouteStyle[i].Hole + MIN_PINORVIACOPPER)
		{
		  PCB->RouteStyle[i].Diameter =
		    PCB->RouteStyle[i].Hole + MIN_PINORVIACOPPER;
		  Message (_
			   ("Increased %s routing style via diameter to %6.2f mils\n"),
			   PCB->RouteStyle[i].Name,
			   0.01 * PCB->RouteStyle[i].Diameter);
		}
	    }
	}

      /* 
       * if we've changed anything, indicate that we need to save the
       * file, redraw things, and make sure we can undo.
       */
      if (changed)
	{
	  SetChangedFlag (true);
	  Redraw ();
	  IncrementUndoSerialNumber ();
	}
    }

  /* restore mapping on/off */
  vendorMapEnable = state;
}
Exemple #10
0
static int
PrintBOM (void)
{
  char utcTime[64];
  Coord x, y;
  double theta = 0.0;
  double sumx, sumy;
  double pin1x = 0.0, pin1y = 0.0, pin1angle = 0.0;
  double pin2x = 0.0, pin2y = 0.0;
  int found_pin1;
  int found_pin2;
  int pin_cnt;
  time_t currenttime;
  FILE *fp;
  BomList *bom = NULL;
  char *name, *descr, *value;

  fp = fopen (xy_filename, "w");
  if (!fp)
    {
      gui->log ("Cannot open file %s for writing\n", xy_filename);
      return 1;
    }

  /* Create a portable timestamp. */
  currenttime = time (NULL);
  {
    /* avoid gcc complaints */
    const char *fmt = "%c UTC";
    strftime (utcTime, sizeof (utcTime), fmt, gmtime (&currenttime));
  }
  fprintf (fp, "# PcbXY Version 1.0\n");
  fprintf (fp, "# Date: %s\n", utcTime);
  fprintf (fp, "# Author: %s\n", pcb_author ());
  fprintf (fp, "# Title: %s - PCB X-Y\n", UNKNOWN (PCB->Name));
  fprintf (fp, "# RefDes, Description, Value, X, Y, rotation, top/bottom\n");
  fprintf (fp, "# X,Y in %s.  rotation in degrees.\n", xy_unit->in_suffix);
  fprintf (fp, "# --------------------------------------------\n");

  /*
   * For each element we calculate the centroid of the footprint.
   * In addition, we need to extract some notion of rotation.  
   * While here generate the BOM list
   */

  ELEMENT_LOOP (PCB->Data);
  {

    /* initialize our pin count and our totals for finding the
       centriod */
    pin_cnt = 0;
    sumx = 0.0;
    sumy = 0.0;
    found_pin1 = 0;
    found_pin2 = 0;

    /* insert this component into the bill of materials list */
    bom = bom_insert ((char *)UNKNOWN (NAMEONPCB_NAME (element)),
		      (char *)UNKNOWN (DESCRIPTION_NAME (element)),
		      (char *)UNKNOWN (VALUE_NAME (element)), bom);


    /*
     * iterate over the pins and pads keeping a running count of how
     * many pins/pads total and the sum of x and y coordinates
     * 
     * While we're at it, store the location of pin/pad #1 and #2 if
     * we can find them
     */

    PIN_LOOP (element);
    {
      sumx += (double) pin->X;
      sumy += (double) pin->Y;
      pin_cnt++;

      if (NSTRCMP (pin->Number, "1") == 0)
	{
	  pin1x = (double) pin->X;
	  pin1y = (double) pin->Y;
	  pin1angle = 0.0;	/* pins have no notion of angle */
	  found_pin1 = 1;
	}
      else if (NSTRCMP (pin->Number, "2") == 0)
	{
	  pin2x = (double) pin->X;
	  pin2y = (double) pin->Y;
	  found_pin2 = 1;
	}
    }
    END_LOOP;

    PAD_LOOP (element);
    {
      sumx += (pad->Point1.X + pad->Point2.X) / 2.0;
      sumy += (pad->Point1.Y + pad->Point2.Y) / 2.0;
      pin_cnt++;

      if (NSTRCMP (pad->Number, "1") == 0)
	{
	  pin1x = (double) (pad->Point1.X + pad->Point2.X) / 2.0;
	  pin1y = (double) (pad->Point1.Y + pad->Point2.Y) / 2.0;
	  /*
	   * NOTE:  We swap the Y points because in PCB, the Y-axis
	   * is inverted.  Increasing Y moves down.  We want to deal
	   * in the usual increasing Y moves up coordinates though.
	   */
	  pin1angle = (180.0 / M_PI) * atan2 (pad->Point1.Y - pad->Point2.Y,
					      pad->Point2.X - pad->Point1.X);
	  found_pin1 = 1;
	}
      else if (NSTRCMP (pad->Number, "2") == 0)
	{
	  pin2x = (double) (pad->Point1.X + pad->Point2.X) / 2.0;
	  pin2y = (double) (pad->Point1.Y + pad->Point2.Y) / 2.0;
	  found_pin2 = 1;
	}

    }
    END_LOOP;

    if (pin_cnt > 0)
      {
	x = sumx / (double) pin_cnt;
	y = sumy / (double) pin_cnt;

	if (found_pin1)
	  {
	    /* recenter pin #1 onto the axis which cross at the part
	       centroid */
	    pin1x -= x;
	    pin1y -= y;
	    pin1y = -1.0 * pin1y;

	    /* if only 1 pin, use pin 1's angle */
	    if (pin_cnt == 1)
	      theta = pin1angle;
	    else
	      {
		/* if pin #1 is at (0,0) use pin #2 for rotation */
		if ((pin1x == 0.0) && (pin1y == 0.0))
		  {
		    if (found_pin2)
		      theta = xyToAngle (pin2x, pin2y);
		    else
		      {
			Message
			  ("PrintBOM(): unable to figure out angle of element\n"
			   "     %s because pin #1 is at the centroid of the part.\n"
			   "     and I could not find pin #2's location\n"
			   "     Setting to %g degrees\n",
			   UNKNOWN (NAMEONPCB_NAME (element)), theta);
		      }
		  }
		else
		  theta = xyToAngle (pin1x, pin1y);
	      }
	  }
	/* we did not find pin #1 */
	else
	  {
	    theta = 0.0;
	    Message
	      ("PrintBOM(): unable to figure out angle because I could\n"
	       "     not find pin #1 of element %s\n"
	       "     Setting to %g degrees\n",
	       UNKNOWN (NAMEONPCB_NAME (element)), theta);
	  }

	name = CleanBOMString ((char *)UNKNOWN (NAMEONPCB_NAME (element)));
	descr = CleanBOMString ((char *)UNKNOWN (DESCRIPTION_NAME (element)));
	value = CleanBOMString ((char *)UNKNOWN (VALUE_NAME (element)));

 	y = PCB->MaxHeight - y;
	pcb_fprintf (fp, "%m+%s,\"%s\",\"%s\",%mS,%.2mS,%g,%s\n",
		     xy_unit->allow, name, descr, value, x, y,
		     theta, FRONT (element) == 1 ? "top" : "bottom");
	free (name);
	free (descr);
	free (value);
      }
  }
  END_LOOP;

  fclose (fp);

  /* Now print out a Bill of Materials file */

  fp = fopen (bom_filename, "w");
  if (!fp)
    {
      gui->log ("Cannot open file %s for writing\n", bom_filename);
      print_and_free (NULL, bom);
      return 1;
    }

  fprintf (fp, "# PcbBOM Version 1.0\n");
  fprintf (fp, "# Date: %s\n", utcTime);
  fprintf (fp, "# Author: %s\n", pcb_author ());
  fprintf (fp, "# Title: %s - PCB BOM\n", UNKNOWN (PCB->Name));
  fprintf (fp, "# Quantity, Description, Value, RefDes\n");
  fprintf (fp, "# --------------------------------------------\n");

  print_and_free (fp, bom);

  fclose (fp);

  return (0);
}