Example #1
0
File: insert.c Project: thequux/pcb
/* ---------------------------------------------------------------------------
 * inserts a point into a rat-line
 */
static void *
InsertPointIntoRat (RatTypePtr Rat)
{
  LineTypePtr newone;

  newone = CreateDrawnLineOnLayer (CURRENT, Rat->Point1.X, Rat->Point1.Y,
				InsertX, InsertY, Settings.LineThickness,
				2 * Settings.Keepaway, Rat->Flags);
  if (!newone)
    return newone;
  AddObjectToCreateUndoList (LINE_TYPE, CURRENT, newone, newone);
  EraseRat (Rat);
  DrawLine (CURRENT, newone, 0);
  newone = CreateDrawnLineOnLayer (CURRENT, Rat->Point2.X, Rat->Point2.Y,
				InsertX, InsertY, Settings.LineThickness,
				2 * Settings.Keepaway, Rat->Flags);
  if (newone)
    {
      AddObjectToCreateUndoList (LINE_TYPE, CURRENT, newone, newone);
      DrawLine (CURRENT, newone, 0);
    }
  MoveObjectToRemoveUndoList (RATLINE_TYPE, Rat, Rat, Rat);
  Draw ();
  return (newone);
}
Example #2
0
/* ---------------------------------------------------------------------------
 * moves a line between layers
 */
static void *
MoveRatToLayer (RatType *Rat)
{
  LineTypePtr newone;
  //Coord X1 = Rat->Point1.X, Y1 = Rat->Point1.Y;
  //Coord X1 = Rat->Point1.X, Y1 = Rat->Point1.Y;
  // if VIAFLAG
  //   if we're on a pin, add a thermal
  //   else make a via and a wire, but 0-length wire not good
  // else as before

  newone = CreateNewLineOnLayer (Dest, Rat->Point1.X, Rat->Point1.Y,
			      Rat->Point2.X, Rat->Point2.Y,
			      Settings.LineThickness, 2 * Settings.Keepaway,
			      Rat->Flags);
  if (TEST_FLAG (CLEARNEWFLAG, PCB))
    SET_FLAG (CLEARLINEFLAG, newone);
  if (!newone)
    return (NULL);
  AddObjectToCreateUndoList (LINE_TYPE, Dest, newone, newone);
  if (PCB->RatOn)
    EraseRat (Rat);
  MoveObjectToRemoveUndoList (RATLINE_TYPE, Rat, Rat, Rat);
  DrawLine (Dest, newone);
  Draw ();
  return (newone);
}
Example #3
0
/* ---------------------------------------------------------------------------
 * copies an element onto the PCB.  Then does a draw. 
 */
static void *
CopyElement (ElementType *Element)
{

#ifdef DEBUG
  printf("Entered CopyElement, trying to copy element %s\n",
	 Element->Name[1].TextString);
#endif

  ElementType *element = CopyElementLowLevel (PCB->Data, Element,
                                              TEST_FLAG (UNIQUENAMEFLAG, PCB),
                                              DeltaX, DeltaY, NOCOPY_FLAGS);

  /* this call clears the polygons */
  AddObjectToCreateUndoList (ELEMENT_TYPE, element, element, element);
  if (PCB->ElementOn && (FRONT (element) || PCB->InvisibleObjectsOn))
    {
      DrawElementName (element);
      DrawElementPackage (element);
    }
  if (PCB->PinOn)
    {
      DrawElementPinsAndPads (element);
    }
#ifdef DEBUG
  printf(" ... Leaving CopyElement.\n");
#endif
  return (element);
}
Example #4
0
File: insert.c Project: thequux/pcb
/* ---------------------------------------------------------------------------
 * inserts a point into a line
 */
static void *
InsertPointIntoLine (LayerTypePtr Layer, LineTypePtr Line)
{
  LineTypePtr line;
  LocationType X, Y;

  if (((Line->Point1.X == InsertX) && (Line->Point1.Y == InsertY)) ||
      ((Line->Point2.X == InsertX) && (Line->Point2.Y == InsertY)))
    return (NULL);
  X = Line->Point2.X;
  Y = Line->Point2.Y;
  AddObjectToMoveUndoList (LINEPOINT_TYPE, Layer, Line, &Line->Point2,
			   InsertX - X, InsertY - Y);
  EraseLine (Line);
  r_delete_entry (Layer->line_tree, (BoxTypePtr) Line);
  Line->Point2.X = InsertX;
  Line->Point2.Y = InsertY;
  SetLineBoundingBox (Line);
  r_insert_entry (Layer->line_tree, (BoxTypePtr) Line, 0);
  DrawLine (Layer, Line, 0);
  /* we must create after playing with Line since creation may
   * invalidate the line pointer
   */
  if ((line = CreateDrawnLineOnLayer (Layer, InsertX, InsertY,
				      X, Y,
				      Line->Thickness, Line->Clearance,
				      Line->Flags)))
    {
      AddObjectToCreateUndoList (LINE_TYPE, Layer, line, line);
      DrawLine (Layer, line, 0);
      /* creation call adds it to the rtree */
    }
  Draw ();
  return (line);
}
Example #5
0
/*
 * Wrapper for CreateNewLineOnLayer that takes vectors and deals with Undo
 */
static LineType *
CreateVectorLineOnLayer(LayerType *layer, Vector a, Vector b, int thickness, int clearance, FlagType flags)
{
	LineType *line;

	line = CreateNewLineOnLayer(layer, a[0], a[1], b[0], b[1], thickness, clearance, flags);
	if (line) {
		AddObjectToCreateUndoList (LINE_TYPE, layer, line, line);
	}
	return line;
}
Example #6
0
/* ---------------------------------------------------------------------------
 * copies a text 
 */
static void *
CopyText (LayerType *Layer, TextType *Text)
{
  TextType *text;

  text = CreateNewText (Layer, &PCB->Font, Text->X + DeltaX,
			Text->Y + DeltaY, Text->Direction,
			Text->Scale, Text->TextString,
			MaskFlags (Text->Flags, NOCOPY_FLAGS));
  DrawText (Layer, text);
  AddObjectToCreateUndoList (TEXT_TYPE, Layer, text, text);
  return (text);
}
Example #7
0
static void
replace_one_footprint_aux(ElementTypePtr old_element,
                          PadOrPinType* old1_pp, PadOrPinType* old2_pp,
                          ElementTypePtr copy_element,
                          PadOrPinType* copy1_pp, PadOrPinType* copy2_pp)
{
  Boolean two_points = (old2_pp && copy2_pp);
  Boolean reflect = IS_REFLECTED(copy_element, old_element);

  debug_log("Reflect?: %s\n", (reflect ? "yes" : "no"));
  if (reflect) {
    /* Change side of board */
    ChangeElementSide(copy_element, 0);
  }

  CheapPointType copy1_pt = pad_or_pin_center(copy1_pp);
  CheapPointType old1_pt = pad_or_pin_center(old1_pp);

  BYTE rot_steps = 0;
  if (two_points) {
    /* Calculate nearest rotation steps */
    CheapPointType copy2_pt = pad_or_pin_center(copy2_pp);
    CheapPointType old2_pt = pad_or_pin_center(old2_pp);
    rot_steps =
      calculate_rotation_steps(copy1_pt, copy2_pt, old1_pt, old2_pt);
  }
  if (rot_steps) {
    /* Rotate copy */
    RotateElementLowLevel(PCB->Data, copy_element, 0, 0, rot_steps);
    /* Recalculate since copy_element has changed. */
    copy1_pt = pad_or_pin_center(copy1_pp);
  }

  /* Calculate translation */
  LocationType dx = old1_pt.X - copy1_pt.X;
  LocationType dy = old1_pt.Y - copy1_pt.Y;
  /* Move element */
  MoveElementLowLevel(PCB->Data, copy_element, dx, dy);

  /* Transfer pad/pin text and names. */
  transfer_text(old_element, copy_element);
  transfer_names(old_element, copy_element);
  transfer_flags(old_element, copy_element);
  SetElementBoundingBox(PCB->Data, copy_element, &PCB->Font);

  AddObjectToCreateUndoList(ELEMENT_TYPE,
                            copy_element, copy_element, copy_element);
  /* Remove old element. */
  MoveObjectToRemoveUndoList(ELEMENT_TYPE,
                             old_element, old_element, old_element);
}
Example #8
0
/* ---------------------------------------------------------------------------
 * copies an arc
 */
static void *
CopyArc (LayerType *Layer, ArcType *Arc)
{
  ArcType *arc;

  arc = CreateNewArcOnLayer (Layer, Arc->X + DeltaX,
			     Arc->Y + DeltaY, Arc->Width, Arc->Height, Arc->StartAngle,
			     Arc->Delta, Arc->Thickness, Arc->Clearance,
			     MaskFlags (Arc->Flags, NOCOPY_FLAGS));
  if (!arc)
    return (arc);
  DrawArc (Layer, arc);
  AddObjectToCreateUndoList (ARC_TYPE, Layer, arc, arc);
  return (arc);
}
Example #9
0
/* ---------------------------------------------------------------------------
 * copies a via 
 */
static void *
CopyVia (PinType *Via)
{
  PinType *via;

  via = CreateNewVia (PCB->Data, Via->X + DeltaX, Via->Y + DeltaY,
		      Via->Thickness, Via->Clearance, Via->Mask,
		      Via->DrillingHole, Via->Name,
		      MaskFlags (Via->Flags, NOCOPY_FLAGS));
  if (!via)
    return (via);
  DrawVia (via);
  AddObjectToCreateUndoList (VIA_TYPE, via, via, via);
  return (via);
}
Example #10
0
/* ---------------------------------------------------------------------------
 * copies a polygon 
 */
static void *
CopyPolygon (LayerType *Layer, PolygonType *Polygon)
{
  PolygonType *polygon;

  polygon = CreateNewPolygon (Layer, NoFlags ());
  CopyPolygonLowLevel (polygon, Polygon);
  MovePolygonLowLevel (polygon, DeltaX, DeltaY);
  if (!Layer->polygon_tree)
    Layer->polygon_tree = r_create_tree (NULL, 0, 0);
  r_insert_entry (Layer->polygon_tree, (BoxType *) polygon, 0);
  InitClip (PCB->Data, Layer, polygon);
  DrawPolygon (Layer, polygon);
  AddObjectToCreateUndoList (POLYGON_TYPE, Layer, polygon, polygon);
  return (polygon);
}
Example #11
0
static int
moveline_callback (const BoxType * b, void *cl)
{
  struct via_info *i = (struct via_info *) cl;
  PinTypePtr via;

  if ((via =
       CreateNewVia (PCB->Data, i->X, i->Y,
		     Settings.ViaThickness, 2 * Settings.Keepaway,
		     NOFLAG, Settings.ViaDrillingHole, NULL,
		     NoFlags ())) != NULL)
    {
      AddObjectToCreateUndoList (VIA_TYPE, via, via, via);
      DrawVia (via);
    }
  longjmp (i->env, 1);
}
Example #12
0
/* ---------------------------------------------------------------------------
 * copies a line 
 */
static void *
CopyLine (LayerType *Layer, LineType *Line)
{
  LineType *line;

  line = CreateDrawnLineOnLayer (Layer, Line->Point1.X + DeltaX,
				 Line->Point1.Y + DeltaY,
				 Line->Point2.X + DeltaX,
				 Line->Point2.Y + DeltaY, Line->Thickness,
				 Line->Clearance,
				 MaskFlags (Line->Flags, NOCOPY_FLAGS));
  if (!line)
    return (line);
  if (Line->Number)
    line->Number = strdup (Line->Number);
  DrawLine (Layer, line);
  AddObjectToCreateUndoList (LINE_TYPE, Layer, line, line);
  return (line);
}
Example #13
0
/* ---------------------------------------------------------------------------
 * copies a line 
 */
static void *
CopyLine (LayerTypePtr Layer, LineTypePtr Line)
{
  LineTypePtr line;

  line = CreateDrawnLineOnLayer (Layer, Line->Point1.X + DeltaX,
				 Line->Point1.Y + DeltaY,
				 Line->Point2.X + DeltaX,
				 Line->Point2.Y + DeltaY, Line->Thickness,
				 Line->Clearance,
				 MaskFlags (Line->Flags, FOUNDFLAG));
  if (!line)
    return (line);
  if (Line->Number)
    line->Number = MyStrdup (Line->Number, "CopyLine");
  DrawLine (Layer, line, 0);
  AddObjectToCreateUndoList (LINE_TYPE, Layer, line, line);
  return (line);
}
Example #14
0
File: rats.c Project: rlutz/pcb
/*!
 * \brief Draw a rat net (tree) having the shortest lines.
 *
 * This also frees the subnet memory as they are consumed.
 *
 * \note The \c Netl we are passed is NOT the main netlist - it's the
 * connectivity for ONE net.
 * It represents the CURRENT connectivity state for the net, with each
 * Netl->Net[N] representing one copper-connected subset of the net.
 *
 * Everything inside the NetList Netl should be connected together.
 *
 * Each Net in \c Netl is a group of Connections which are already
 * connected together somehow, either by real wires or by rats we've
 * already drawn.
 *
 * Each Connection is a vertex within that blob of connected items.
 *
 * This loop finds the closest vertex pairs between each blob and draws
 * rats that merge the blobs until there's just one big blob.
 *
 * Just to clarify, with some examples:
 *
 * Each \c Netl is one full net from a netlist, like from gnetlist.
 *
 * Each Netl->Net[N] is a subset of that net that's already
 * physically connected on the pcb.
 *
 * So a new design with no traces yet, would have a huge list of Net[N],
 * each with one pin in it.
 *
 * A fully routed design would have one Net[N] with all the pins
 * (for that net) in it.
 */
static bool
DrawShortestRats (NetListType *Netl, void (*funcp) (register ConnectionType *, register ConnectionType *, register RouteStyleType *))
{
  RatType *line;
  register float distance, temp;
  register ConnectionType *conn1, *conn2, *firstpoint, *secondpoint;
  PolygonType *polygon;
  bool changed = false;
  bool havepoints;
  Cardinal n, m, j;
  NetType *next, *subnet, *theSubnet = NULL;

  /* This is just a sanity check, to make sure we're passed
   * *something*.
   */
  if (!Netl || Netl->NetN < 1)
    return false;

  /*
   * We keep doing this do/while loop until everything's connected.
   * I.e. once per rat we add.
   */
  distance = 0.0;
  havepoints = true; /* so we run the loop at least once */
  while (Netl->NetN > 1 && havepoints)
    {
      /* This is the top of the "find one rat" logic.  */
      havepoints = false;
      firstpoint = secondpoint = NULL;

      /* Test Net[0] vs Net[N] for N=1..max.  Find the shortest
	 distance between any two points in different blobs.  */
      subnet = &Netl->Net[0];
      for (j = 1; j < Netl->NetN; j++)
	{
	  /*
	   * Scan between Net[0] blob (subnet) and Net[N] blob (next).
	   * Note the shortest distance we find.
	   */
	  next = &Netl->Net[j];
	  for (n = subnet->ConnectionN - 1; n != -1; n--)
	    {
	      conn1 = &subnet->Connection[n];
	      for (m = next->ConnectionN - 1; m != -1; m--)
		{
		  conn2 = &next->Connection[m];
		  /*
		   * At this point, conn1 and conn2 are two pins in
		   * different blobs of the same net.  See how far
		   * apart they are, and if they're "closer" than what
		   * we already have.
		   */

		  /*
		   * Prefer to connect Connections over polygons to the
		   * polygons (ie assume the user wants a via to a plane,
		   * not a daisy chain).  Further prefer to pick an existing
		   * via in the Net to make that connection.
		   */
		  if (conn1->type == POLYGON_TYPE &&
		      (polygon = (PolygonType *)conn1->ptr2) &&
		      !(distance == 0 &&
		        firstpoint && firstpoint->type == VIA_TYPE) &&
		      IsPointInPolygonIgnoreHoles (conn2->X, conn2->Y, polygon))
		    {
		      distance = 0;
		      firstpoint = conn2;
		      secondpoint = conn1;
		      theSubnet = next;
		      havepoints = true;
		    }
		  else if (conn2->type == POLYGON_TYPE &&
		      (polygon = (PolygonType *)conn2->ptr2) &&
		      !(distance == 0 &&
		        firstpoint && firstpoint->type == VIA_TYPE) &&
		      IsPointInPolygonIgnoreHoles (conn1->X, conn1->Y, polygon))
		    {
		      distance = 0;
		      firstpoint = conn1;
		      secondpoint = conn2;
		      theSubnet = next;
		      havepoints = true;
		    }
		  else if ((temp = SQUARE (conn1->X - conn2->X) +
		       SQUARE (conn1->Y - conn2->Y)) < distance || !firstpoint)
		    {
		      distance = temp;
		      firstpoint = conn1;
		      secondpoint = conn2;
		      theSubnet = next;
		      havepoints = true;
		    }
		}
	    }
	}

      /*
       * If HAVEPOINTS is true, we've found a pair of points in two
       * separate blobs of the net, and need to connect them together.
       */
      if (havepoints)
	{
	  if (funcp)
	    {
	      (*funcp) (firstpoint, secondpoint, subnet->Style);
	    }
	  else
	    {
	      /* found the shortest distance subnet, draw the rat */
	      if ((line = CreateNewRat (PCB->Data,
					firstpoint->X, firstpoint->Y,
					secondpoint->X, secondpoint->Y,
					firstpoint->group, secondpoint->group,
					Settings.RatThickness,
					NoFlags ())) != NULL)
		{
		  if (distance == 0)
		    SET_FLAG (VIAFLAG, line);
		  AddObjectToCreateUndoList (RATLINE_TYPE, line, line, line);
		  DrawRat (line);
		  changed = true;
		}
	    }

	  /* copy theSubnet into the current subnet */
	  TransferNet (Netl, theSubnet, subnet);
	}
    }

  /* presently nothing to do with the new subnet */
  /* so we throw it away and free the space */
  FreeNetMemory (&Netl->Net[--(Netl->NetN)]);
  /* Sadly adding a rat line messes up the sorted arrays in connection finder */
  /* hace: perhaps not necessarily now that they aren't stored in normal layers */
  if (changed)
    {
      FreeConnectionLookupMemory ();
      InitConnectionLookup ();
    }
  return (changed);
}