www.delorie.com/archives/browse.cgi   search  
Mail Archives: geda-user/2015/06/25/12:38:39

X-Authentication-Warning: delorie.com: mail set sender to geda-user-bounces using -f
X-Recipient: geda-user AT delorie DOT com
X-Envelope-From: paubert AT iram DOT es
Date: Thu, 25 Jun 2015 18:37:36 +0200
From: "Gabriel Paubert (paubert AT iram DOT es)" <geda-user AT delorie DOT com>
To: geda-user AT delorie DOT com
Subject: [geda-user] [RFC][PATCH] PCB: Allow non rounded clearances for
rectangular/square pins and pads
Message-ID: <20150625163731.GA18117@visitor2.iram.es>
MIME-Version: 1.0
User-Agent: Mutt/1.5.21 (2010-09-15)
X-Spamina-Bogosity: Unsure
X-Spamina-Spam-Score: -0.2 (/)
X-Spamina-Spam-Report: Content analysis details: (-0.2 points)
pts rule name description
---- ---------------------- --------------------------------------------------
-1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP
0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked.
See
http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block
for more information.
[URIs: pcb-menu.res.in]
0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60%
[score: 0.5000]
Reply-To: geda-user AT delorie DOT com

--SUOF0GtieIMvvwua
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline


    Hi,

this is only a heads-up on what I've been doing in the last few days.
The code is not in shape for inclusion but I thought that it's possible
to share it now at least to get some feedback.

Actually, I'm chasing the annoying bug that sometimes happens of a small
sliver of copper that creates shorts under very specific conditions and
I've been diving in the polygon code for 2 days and a half, because it
caused systematic problems when generating Gerber files for a moderately
complex board: 80x200mm, ~680 components, but "only" 2000 pads since it's
relativly high frequency (up to 1GHz) and roughly half the components are 
capacitors of various sizes (60 of them 0201, the rest mostly 0603 with 
quite a few 1206 and some 0402 thrown in, plus three EIA7343 tantalum).

Anyway, the patch is appended, it boils down to:
- adding a new flag called "squareclearance" that changes the behaviour
  of the clearance for non-circular pads and pins.
- enable this feature by essentially copying the code fragments for the 
  "square" flag and renaming square to squarecleareance with appropriate
  UPPER/lower/CamelCase.
- map the corresponding Toggle action to Alt-Q

Existing files should not be affected at all by the patch. As far as I can
see, the result is bug-invariant as long as you don't use the new feature. 

There are areas where I find the result much nicer, aesthetically speaking.

Generated Gerber files are much smaller, in the board I speak of above,
the total size drops from ~5MB to ~260kB when all square/rectangular
pads are converted to square clearance, but this was obviously not
at all the goal of the patch. Optimally the Gerber driver should use
circular primitives to define these contours instead of linear
approximations. The GUI interface also seems to be a bit more responsive
and have less lag when moving the cursor on my largest design (the PCB
file is over 1MB, and the load time is noticeable on a Core2Duo).

I have more work in progress, but it is even in a less presentable
state:
- fix the sides of clearance for non circular pins/pads, if you look at 
  them carefully, you'll notice that the straight lines are often not 
  exactly parallel to the pad edge. For now I have code apparently working 
  for pins and pads, but not yet for thermals.

- change some of the internal ABI of the polygon code that really
  annoyed me, as well as reordering some structures for better packing.

    Regards,
    Gabriel


--SUOF0GtieIMvvwua
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=pcbpatch

diff --git a/src/action.c b/src/action.c
index 86b379d..46fd694 100644
--- a/src/action.c
+++ b/src/action.c
@@ -5016,6 +5016,184 @@ ActionClearSquare (int argc, char **argv, Coord x, Coord y)
 
 /* --------------------------------------------------------------------------- */
 
+static const char changesquareclearance_syntax[] =
+  N_("ChangeSquareClearance(ToggleObject)\n"
+  "ChangeSquareClearance(SelectedElements|SelectedPins)\n"
+  "ChangeSquareClearance(Selected|SelectedObjects)");
+
+static const char changesquareclearance_help[] =
+  N_("Changes the square clearance flag of pins and pads.");
+
+/* %start-doc actions ChangeSquareClearance
+
+Note that @code{Pins} means both pins and pads.
+
+@pinshapes
+
+%end-doc */
+
+static int
+ActionChangeSquareClearance (int argc, char **argv, Coord x, Coord y)
+{
+  char *function = ARG (0);
+  if (function)
+    {
+      switch (GetFunctionID (function))
+	{
+	case F_ToggleObject:
+	case F_Object:
+	  {
+	    int type;
+	    void *ptr1, *ptr2, *ptr3;
+
+	    gui->get_coords (_("Select an Object"), &x, &y);
+	    if ((type =
+		 SearchScreen (x, y, CHANGESQUARECLEARANCE_TYPES,
+			       &ptr1, &ptr2, &ptr3)) != NO_TYPE)
+	      if (ChangeObjectSquareClearance (type, ptr1, ptr2, ptr3))
+		SetChangedFlag (true);
+	    break;
+	  }
+
+	case F_SelectedElements:
+	  if (ChangeSelectedSquareClearance (ELEMENT_TYPE))
+	    SetChangedFlag (true);
+	  break;
+
+	case F_SelectedPins:
+	  if (ChangeSelectedSquareClearance (PIN_TYPE | PAD_TYPE))
+	    SetChangedFlag (true);
+	  break;
+
+	case F_Selected:
+	case F_SelectedObjects:
+	  if (ChangeSelectedSquareClearance (PIN_TYPE | PAD_TYPE))
+	    SetChangedFlag (true);
+	  break;
+	}
+    }
+  return 0;
+}
+
+/* --------------------------------------------------------------------------- */
+
+static const char setsquareclearance_syntax[] =
+  N_("SetSquareClearance(ToggleObject|SelectedElements|SelectedPins)");
+
+static const char setsquareclearance_help[] = N_("sets the square clearance flag of objects.");
+
+/* %start-doc actions SetSquareClearance
+
+Note that @code{Pins} means pins and pads.
+
+@pinshapes
+
+%end-doc */
+
+static int
+ActionSetSquareClearance (int argc, char **argv, Coord x, Coord y)
+{
+  char *function = ARG (0);
+  if (function && *function)
+    {
+      switch (GetFunctionID (function))
+	{
+	case F_ToggleObject:
+	case F_Object:
+	  {
+	    int type;
+	    void *ptr1, *ptr2, *ptr3;
+
+	    gui->get_coords (_("Select an Object"), &x, &y);
+	    if ((type =
+		 SearchScreen (x, y, CHANGESQUARECLEARANCE_TYPES,
+			       &ptr1, &ptr2, &ptr3)) != NO_TYPE)
+	      if (SetObjectSquareClearance (type, ptr1, ptr2, ptr3))
+		SetChangedFlag (true);
+	    break;
+	  }
+
+	case F_SelectedElements:
+	  if (SetSelectedSquareClearance (ELEMENT_TYPE))
+	    SetChangedFlag (true);
+	  break;
+
+	case F_SelectedPins:
+	  if (SetSelectedSquareClearance (PIN_TYPE | PAD_TYPE))
+	    SetChangedFlag (true);
+	  break;
+
+	case F_Selected:
+	case F_SelectedObjects:
+	  if (SetSelectedSquareClearance (PIN_TYPE | PAD_TYPE))
+	    SetChangedFlag (true);
+	  break;
+	}
+    }
+  return 0;
+}
+
+/* --------------------------------------------------------------------------- */
+
+static const char clearsquareclearance_syntax[] =
+  N_("ClearSquareClearance(ToggleObject|SelectedElements|SelectedPins)");
+
+static const char clearsquareclearance_help[] =
+  N_("Clears the square clearance of pins and pads.");
+
+/* %start-doc actions ClearSquareClearance
+
+Note that @code{Pins} means pins and pads.
+
+@pinshapes
+
+%end-doc */
+
+static int
+ActionClearSquareClearance (int argc, char **argv, Coord x, Coord y)
+{
+  char *function = ARG (0);
+  if (function && *function)
+    {
+      switch (GetFunctionID (function))
+	{
+	case F_ToggleObject:
+	case F_Object:
+	  {
+	    int type;
+	    void *ptr1, *ptr2, *ptr3;
+
+	    gui->get_coords (_("Select an Object"), &x, &y);
+	    if ((type =
+		 SearchScreen (x, y, CHANGESQUARECLEARANCE_TYPES,
+			       &ptr1, &ptr2, &ptr3)) != NO_TYPE)
+	      if (ClrObjectSquareClearance (type, ptr1, ptr2, ptr3))
+		SetChangedFlag (true);
+	    break;
+	  }
+
+	case F_SelectedElements:
+	  if (ClrSelectedSquareClearance (ELEMENT_TYPE))
+	    SetChangedFlag (true);
+	  break;
+
+	case F_SelectedPins:
+	  if (ClrSelectedSquareClearance (PIN_TYPE | PAD_TYPE))
+	    SetChangedFlag (true);
+	  break;
+
+	case F_Selected:
+	case F_SelectedObjects:
+	  if (ClrSelectedSquareClearance (PIN_TYPE | PAD_TYPE))
+	    SetChangedFlag (true);
+	  break;
+	}
+    }
+  return 0;
+}
+
+/* --------------------------------------------------------------------------- */
+
 static const char changeoctagon_syntax[] =
   N_("ChangeOctagon(Object|ToggleObject|SelectedObjects|Selected)\n"
   "ChangeOctagon(SelectedElements|SelectedPins|SelectedVias)");
@@ -8065,12 +8243,18 @@ HID_Action action_action_list[] = {
   {"ChangeSquare", 0, ActionChangeSquare,
    changesquare_help, changesquare_syntax}
   ,
+  {"ChangeSquareClearance", 0, ActionChangeSquareClearance,
+   changesquareclearance_help, changesquareclearance_syntax}
+  ,
   {"ChangeOctagon", 0, ActionChangeOctagon,
    changeoctagon_help, changeoctagon_syntax}
   ,
   {"ClearSquare", 0, ActionClearSquare,
    clearsquare_help, clearsquare_syntax}
   ,
+  {"ClearSquareClearance", 0, ActionClearSquareClearance,
+   clearsquareclearance_help, clearsquareclearance_syntax}
+  ,
   {"ClearOctagon", 0, ActionClearOctagon,
    clearoctagon_help, clearoctagon_syntax}
   ,
@@ -8152,6 +8336,9 @@ HID_Action action_action_list[] = {
   {"SetSquare", 0, ActionSetSquare,
    setsquare_help, setsquare_syntax}
   ,
+  {"SetSquareClearance", 0, ActionSetSquareClearance,
+   setsquareclearance_help, setsquareclearance_syntax}
+  ,
   {"SetOctagon", 0, ActionSetOctagon,
    setoctagon_help, setoctagon_syntax}
   ,
diff --git a/src/change.c b/src/change.c
index 88d4b9f..2b14db4 100644
--- a/src/change.c
+++ b/src/change.c
@@ -92,12 +92,18 @@ static void *ChangeTextName (LayerType *, TextType *);
 static void *ChangeElementSquare (ElementType *);
 static void *SetElementSquare (ElementType *);
 static void *ClrElementSquare (ElementType *);
+static void *ChangeElementSquareClearance (ElementType *);
+static void *SetElementSquareClearance (ElementType *);
+static void *ClrElementSquareClearance (ElementType *);
 static void *ChangeElementOctagon (ElementType *);
 static void *SetElementOctagon (ElementType *);
 static void *ClrElementOctagon (ElementType *);
 static void *ChangePinSquare (ElementType *, PinType *);
 static void *SetPinSquare (ElementType *, PinType *);
 static void *ClrPinSquare (ElementType *, PinType *);
+static void *ChangePinSquareClearance (ElementType *, PinType *);
+static void *SetPinSquareClearance (ElementType *, PinType *);
+static void *ClrPinSquareClearance (ElementType *, PinType *);
 static void *ChangePinOctagon (ElementType *, PinType *);
 static void *SetPinOctagon (ElementType *, PinType *);
 static void *ClrPinOctagon (ElementType *, PinType *);
@@ -107,6 +113,9 @@ static void *ClrViaOctagon (PinType *);
 static void *ChangePadSquare (ElementType *, PadType *);
 static void *SetPadSquare (ElementType *, PadType *);
 static void *ClrPadSquare (ElementType *, PadType *);
+static void *ChangePadSquareClearance (ElementType *, PadType *);
+static void *SetPadSquareClearance (ElementType *, PadType *);
+static void *ClrPadSquareClearance (ElementType *, PadType *);
 static void *ChangeViaThermal (PinType *);
 static void *ChangePinThermal (ElementType *, PinType *);
 static void *ChangeLineJoin (LayerType *, LineType *);
@@ -210,6 +219,20 @@ static ObjectFunctionType ChangeSquareFunctions = {
   NULL,
   NULL
 };
+static ObjectFunctionType ChangeSquareClearanceFunctions = {
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  ChangeElementSquareClearance,
+  NULL,
+  ChangePinSquareClearance,
+  ChangePadSquareClearance,
+  NULL,
+  NULL,
+  NULL,
+  NULL
+};
 static ObjectFunctionType ChangeJoinFunctions = {
   ChangeLineJoin,
   ChangeTextJoin,
@@ -270,6 +293,20 @@ static ObjectFunctionType SetSquareFunctions = {
   NULL,
   NULL
 };
+static ObjectFunctionType SetSquareClearanceFunctions = {
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  SetElementSquareClearance,
+  NULL,
+  SetPinSquareClearance,
+  SetPadSquareClearance,
+  NULL,
+  NULL,
+  NULL,
+  NULL
+};
 static ObjectFunctionType SetJoinFunctions = {
   SetLineJoin,
   SetTextJoin,
@@ -312,6 +349,20 @@ static ObjectFunctionType ClrSquareFunctions = {
   NULL,
   NULL
 };
+static ObjectFunctionType ClrSquareClearanceFunctions = {
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  ClrElementSquareClearance,
+  NULL,
+  ClrPinSquareClearance,
+  ClrPadSquareClearance,
+  NULL,
+  NULL,
+  NULL,
+  NULL
+};
 static ObjectFunctionType ClrJoinFunctions = {
   ClrLineJoin,
   ClrTextJoin,
@@ -1330,6 +1381,75 @@ ClrElementSquare (ElementType *Element)
 }
 
 /* ---------------------------------------------------------------------------
+ * changes the square clearance flag of all pins on an element
+ */
+static void *
+ChangeElementSquareClearance (ElementType *Element)
+{
+  void *ans = NULL;
+
+  if (TEST_FLAG (LOCKFLAG, Element))
+    return (NULL);
+  PIN_LOOP (Element);
+  {
+    ans = ChangePinSquareClearance (Element, pin);
+  }
+  END_LOOP;
+  PAD_LOOP (Element);
+  {
+    ans = ChangePadSquareClearance (Element, pad);
+  }
+  END_LOOP;
+  return (ans);
+}
+
+/* ---------------------------------------------------------------------------
+ * sets the square clearance flag of all pins on an element
+ */
+static void *
+SetElementSquareClearance (ElementType *Element)
+{
+  void *ans = NULL;
+
+  if (TEST_FLAG (LOCKFLAG, Element))
+    return (NULL);
+  PIN_LOOP (Element);
+  {
+    ans = SetPinSquareClearance (Element, pin);
+  }
+  END_LOOP;
+  PAD_LOOP (Element);
+  {
+    ans = SetPadSquareClearance (Element, pad);
+  }
+  END_LOOP;
+  return (ans);
+}
+
+/* ---------------------------------------------------------------------------
+ * clears the square clearance flag of all pins on an element
+ */
+static void *
+ClrElementSquareClearance (ElementType *Element)
+{
+  void *ans = NULL;
+
+  if (TEST_FLAG (LOCKFLAG, Element))
+    return (NULL);
+  PIN_LOOP (Element);
+  {
+    ans = ClrPinSquareClearance (Element, pin);
+  }
+  END_LOOP;
+  PAD_LOOP (Element);
+  {
+    ans = ClrPadSquareClearance (Element, pad);
+  }
+  END_LOOP;
+  return (ans);
+}
+
+/* ---------------------------------------------------------------------------
  * changes the octagon flags of all pins of an element
  */
 static void *
@@ -1477,6 +1597,96 @@ ClrPinSquare (ElementType *Element, PinType *Pin)
 }
 
 /* ---------------------------------------------------------------------------
+ * changes the square clearance flag of a pad
+ */
+static void *
+ChangePadSquareClearance (ElementType *Element, PadType *Pad)
+{
+  if (TEST_FLAG (LOCKFLAG, Pad))
+    return (NULL);
+  ErasePad (Pad);
+  AddObjectToClearPolyUndoList (PAD_TYPE, Element, Pad, Pad, false);
+  RestoreToPolygon (PCB->Data, PAD_TYPE, Element, Pad);
+  AddObjectToFlagUndoList (PAD_TYPE, Element, Pad, Pad);
+  TOGGLE_FLAG (SQUARECLEARANCEFLAG, Pad);
+  AddObjectToClearPolyUndoList (PAD_TYPE, Element, Pad, Pad, true);
+  ClearFromPolygon (PCB->Data, PAD_TYPE, Element, Pad);
+  DrawPad (Pad);
+  return (Pad);
+}
+
+/* ---------------------------------------------------------------------------
+ * sets the square clearance flag of a pad
+ */
+static void *
+SetPadSquareClearance (ElementType *Element, PadType *Pad)
+{
+
+  if (TEST_FLAG (LOCKFLAG, Pad) || TEST_FLAG (SQUARECLEARANCEFLAG, Pad))
+    return (NULL);
+
+  return (ChangePadSquareClearance (Element, Pad));
+}
+
+
+/* ---------------------------------------------------------------------------
+ * clears the square clearance flag of a pad
+ */
+static void *
+ClrPadSquareClearance (ElementType *Element, PadType *Pad)
+{
+
+  if (TEST_FLAG (LOCKFLAG, Pad) || !TEST_FLAG (SQUARECLEARANCEFLAG, Pad))
+    return (NULL);
+
+  return (ChangePadSquareClearance (Element, Pad));
+}
+
+
+/* ---------------------------------------------------------------------------
+ * changes the square clearance flag of a pin
+ */
+static void *
+ChangePinSquareClearance (ElementType *Element, PinType *Pin)
+{
+  if (TEST_FLAG (LOCKFLAG, Pin))
+    return (NULL);
+  ErasePin (Pin);
+  AddObjectToClearPolyUndoList (PIN_TYPE, Element, Pin, Pin, false);
+  RestoreToPolygon (PCB->Data, PIN_TYPE, Element, Pin);
+  AddObjectToFlagUndoList (PIN_TYPE, Element, Pin, Pin);
+  TOGGLE_FLAG (SQUARECLEARANCEFLAG, Pin);
+  AddObjectToClearPolyUndoList (PIN_TYPE, Element, Pin, Pin, true);
+  ClearFromPolygon (PCB->Data, PIN_TYPE, Element, Pin);
+  DrawPin (Pin);
+  return (Pin);
+}
+
+/* ---------------------------------------------------------------------------
+ * sets the square clearance flag of a pin
+ */
+static void *
+SetPinSquareClearance (ElementType *Element, PinType *Pin)
+{
+  if (TEST_FLAG (LOCKFLAG, Pin) || TEST_FLAG (SQUARECLEARANCEFLAG, Pin))
+    return (NULL);
+
+  return (ChangePinSquareClearance (Element, Pin));
+}
+
+/* ---------------------------------------------------------------------------
+ * clears the square clearance flag of a pin
+ */
+static void *
+ClrPinSquareClearance (ElementType *Element, PinType *Pin)
+{
+  if (TEST_FLAG (LOCKFLAG, Pin) || !TEST_FLAG (SQUARECLEARANCEFLAG, Pin))
+    return (NULL);
+
+  return (ChangePinSquareClearance (Element, Pin));
+}
+
+/* ---------------------------------------------------------------------------
  * changes the octagon flag of a via 
  */
 static void *
@@ -1859,6 +2069,60 @@ ClrSelectedSquare (int types)
 }
 
 /* ----------------------------------------------------------------------
+ * changes the square clearance flag of all selected and visible pins or pads
+ * returns true if anything has changed
+ */
+bool
+ChangeSelectedSquareClearance (int types)
+{
+  bool change = false;
+
+  change = SelectedOperation (&ChangeSquareClearanceFunctions, false, types);
+  if (change)
+    {
+      Draw ();
+      IncrementUndoSerialNumber ();
+    }
+  return (change);
+}
+
+/* ----------------------------------------------------------------------
+ * sets the square clearance flag of all selected and visible pins or pads
+ * returns true if anything has changed
+ */
+bool
+SetSelectedSquareClearance (int types)
+{
+  bool change = false;
+
+  change = SelectedOperation (&SetSquareClearanceFunctions, false, types);
+  if (change)
+    {
+      Draw ();
+      IncrementUndoSerialNumber ();
+    }
+  return (change);
+}
+
+/* ----------------------------------------------------------------------
+ * clears the square clearance flag of all selected and visible pins or pads
+ * returns true if anything has changed
+ */
+bool
+ClrSelectedSquareClearance (int types)
+{
+  bool change = false;
+
+  change = SelectedOperation (&ClrSquareClearanceFunctions, false, types);
+  if (change)
+    {
+      Draw ();
+      IncrementUndoSerialNumber ();
+    }
+  return (change);
+}
+
+/* ----------------------------------------------------------------------
  * changes the octagon-flag of all selected and visible pins and vias
  * returns true if anything has changed
  */
@@ -2200,6 +2464,55 @@ ClrObjectSquare (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
 }
 
 /* ---------------------------------------------------------------------------
+ * changes the square clearance flag of the passed object
+ * Returns true if anything is changed
+ */
+bool
+ChangeObjectSquareClearance (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
+{
+  if (ObjectOperation (&ChangeSquareClearanceFunctions, Type, Ptr1, Ptr2, Ptr3) !=
+      NULL)
+    {
+      Draw ();
+      IncrementUndoSerialNumber ();
+      return (true);
+    }
+  return (false);
+}
+
+/* ---------------------------------------------------------------------------
+ * sets the square clearance flag of the passed object
+ * Returns true if anything is changed
+ */
+bool
+SetObjectSquareClearance (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
+{
+  if (ObjectOperation (&SetSquareClearanceFunctions, Type, Ptr1, Ptr2, Ptr3) != NULL)
+    {
+      Draw ();
+      IncrementUndoSerialNumber ();
+      return (true);
+    }
+  return (false);
+}
+
+/* ---------------------------------------------------------------------------
+ * clears the square-flag of the passed object
+ * Returns true if anything is changed
+ */
+bool
+ClrObjectSquareClearance (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
+{
+  if (ObjectOperation (&ClrSquareClearanceFunctions, Type, Ptr1, Ptr2, Ptr3) != NULL)
+    {
+      Draw ();
+      IncrementUndoSerialNumber ();
+      return (true);
+    }
+  return (false);
+}
+
+/* ---------------------------------------------------------------------------
  * changes the octagon-flag of the passed object
  * Returns true if anything is changed
  */
diff --git a/src/change.h b/src/change.h
index f42842a..6abb767 100644
--- a/src/change.h
+++ b/src/change.h
@@ -52,6 +52,9 @@
 #define	CHANGESQUARE_TYPES     \
 	(ELEMENT_TYPE | PIN_TYPE | PAD_TYPE)
 
+#define	CHANGESQUARECLEARANCE_TYPES     \
+	(ELEMENT_TYPE | PIN_TYPE | PAD_TYPE)
+
 #define	CHANGEOCTAGON_TYPES     \
 	(ELEMENT_TYPE | PIN_TYPE | VIA_TYPE)
 
@@ -76,6 +79,9 @@ bool ClrSelectedJoin (int);
 bool ChangeSelectedSquare (int);
 bool SetSelectedSquare (int);
 bool ClrSelectedSquare (int);
+bool ChangeSelectedSquareClearance (int);
+bool SetSelectedSquareClearance (int);
+bool ClrSelectedSquareClearance (int);
 bool ChangeSelectedThermals (int, int);
 bool ChangeSelectedHole (void);
 bool ChangeSelectedPaste (void);
@@ -100,6 +106,9 @@ bool ClrObjectJoin (int, void *, void *, void *);
 bool ChangeObjectSquare (int, void *, void *, void *);
 bool SetObjectSquare (int, void *, void *, void *);
 bool ClrObjectSquare (int, void *, void *, void *);
+bool ChangeObjectSquareClearance (int, void *, void *, void *);
+bool SetObjectSquareClearance (int, void *, void *, void *);
+bool ClrObjectSquareClearance (int, void *, void *, void *);
 bool ChangeObjectOctagon (int, void *, void *, void *);
 bool SetObjectOctagon (int, void *, void *, void *);
 bool ClrObjectOctagon (int, void *, void *, void *);
diff --git a/src/const.h b/src/const.h
index 08fe253..13eb5ef 100644
--- a/src/const.h
+++ b/src/const.h
@@ -224,7 +224,7 @@ If set, this object has been as physically connected by @code{FindConnection()}.
                                         /* also pinout text for pins is vertical */
 #define VISITFLAG               0x8000  /* marker to avoid re-visiting an object */
 #define CONNECTEDFLAG          0x10000  /* flag like FOUND flag, but used to identify physically connected objects (not rats) */
-
+#define SQUARECLEARANCEFLAG    0x20000  /* Do not round the corners of the clearance for rectangular/square pads and pins */ 
 
 #define NOCOPY_FLAGS (FOUNDFLAG | CONNECTEDFLAG)
 
diff --git a/src/gpcb-menu.res.in b/src/gpcb-menu.res.in
index 47bee40..d218c68 100644
--- a/src/gpcb-menu.res.in
+++ b/src/gpcb-menu.res.in
@@ -419,6 +419,7 @@ MainMenu =
     {"Polygon PreviousPoint" a={"P" "<Key>p"} Polygon(PreviousPoint)}
     {"Polygon Close" a={"Shift-P" "Shift<Key>p"} Polygon(Close)}
     {"ChangeSquare Object" a={"Q" "<Key>q"} ChangeSquare(ToggleObject)}
+    {"ChangeSquareClearance Object" a={"Alt-Q" "Alt<Key>q"} ChangeSquareClearance(ToggleObject)}
     {"ChangeSize +" a={"S" "<Key>s"} ChangeSize(Object,+)}
     {"ChangeSize -" a={"Shift-S" "Shift<Key>s"} ChangeSize(Object,-)}
     {"ChangeDrill +5 mil" a={"Alt-S" "Alt<Key>s"} ChangeDrillSize(Object,+5,mil)}
diff --git a/src/pcb-menu.res.in b/src/pcb-menu.res.in
index e37bd7c..f165645 100644
--- a/src/pcb-menu.res.in
+++ b/src/pcb-menu.res.in
@@ -402,6 +402,7 @@ MainMenu =
     {"Polygon PreviousPoint" a={"P" "<Key>p"} Polygon(PreviousPoint)}
     {"Polygon Close" a={"Shift-P" "Shift<Key>p"} Polygon(Close)}
     {"ChangeSquare Object" a={"Q" "<Key>q"} ChangeSquare(Object)}
+    {"ChangeSquareClearance Object" a={"Alt-Q" "Alt<Key>q"} ChangeSquareClearance(Object)}
     {"ChangeSize +" a={"S" "<Key>s"} ChangeSize(Object,+)}
     {"ChangeSize -" a={"Shift-S" "Shift<Key>s"} ChangeSize(Object,-)}
     {"ChangeDrill +5 mil" a={"Alt-S" "Alt<Key>s"} ChangeDrillSize(Object,+5,mil)}
diff --git a/src/polygon.c b/src/polygon.c
index 75e1b9e..a24f659 100644
--- a/src/polygon.c
+++ b/src/polygon.c
@@ -468,6 +468,31 @@ RoundRect (Coord x1, Coord x2, Coord y1, Coord y2, Coord t)
   return ContourToPoly (contour);
 }
 
+/* make a stright rectangle with x1,x2,y1,y2 defining the corners */
+POLYAREA *
+StraightRect (Coord x1, Coord x2, Coord y1, Coord y2)
+{
+  PLINE *contour = NULL;
+  Vector v;
+
+  assert (x2 > x1);
+  assert (y2 > y1);
+  v[0] = x1;
+  v[1] = y1;
+  if ((contour = poly_NewContour (v)) == NULL)
+    return NULL;
+  v[0] = x2;
+  v[1] = y1;
+  poly_InclVertex (contour->head.prev, poly_CreateNode (v));
+  v[0] = x2;
+  v[1] = y2;
+  poly_InclVertex (contour->head.prev, poly_CreateNode (v));
+  v[0] = x1;
+  v[1] = y2;
+  poly_InclVertex (contour->head.prev, poly_CreateNode (v));
+  return ContourToPoly (contour);
+}
+
 #define ARC_ANGLE 5
 static POLYAREA *
 ArcPolyNoIntersect (ArcType * a, Coord thick)
@@ -652,6 +677,54 @@ SquarePadPoly (PadType * pad, Coord clear)
   d =
     sqrt (SQUARE (pad->Point1.X - pad->Point2.X) +
           SQUARE (pad->Point1.Y - pad->Point2.Y));
+
+  if (TEST_FLAG(SQUARECLEARANCEFLAG, pad))
+    { 
+      if (d != 0)
+        {
+	  double a = (clear + 1)/2/d;
+	  Coord dx = t->Point1.X - t->Point2.X;
+	  Coord dy = t->Point1.Y - t->Point2.Y;
+	  tx = lrint((dy+dx) * a);
+	  ty = lrint((dy-dx) * a);
+	}
+      else
+        {
+          tx = (clear + 1)/2;
+	  ty = tx;
+	}
+      t->Point1.X += tx;
+      t->Point1.Y += ty;
+      t->Point2.X -= tx;
+      t->Point2.Y -= ty;
+      c->Point1.X -= ty;
+      c->Point1.Y += tx;
+      c->Point2.X += ty;
+      c->Point2.Y -= tx;
+
+      v[0] = c->Point1.X;
+      v[1] = c->Point1.Y;
+
+      if ((contour = poly_NewContour (v)) == NULL)
+	      return 0;
+
+      v[0] = t->Point2.X;
+      v[1] = t->Point2.Y;
+
+      poly_InclVertex (contour->head.prev, poly_CreateNode (v));
+
+      v[0] = c->Point2.X;
+      v[1] = c->Point2.Y;
+
+      poly_InclVertex (contour->head.prev, poly_CreateNode (v));
+
+      v[0] = t->Point1.X;
+      v[1] = t->Point1.Y;
+
+      poly_InclVertex (contour->head.prev, poly_CreateNode (v));
+      return ContourToPoly (contour);
+    }
+  /* Rounded rectangle clearance */
   if (d != 0)
     {
       double a = halfthick / d;
@@ -760,9 +833,18 @@ PinPoly (PinType * pin, Coord thick, Coord clear)
 
   if (TEST_FLAG (SQUAREFLAG, pin))
     {
-      size = (thick + 1) / 2;
-      return RoundRect (pin->X - size, pin->X + size, pin->Y - size,
-                        pin->Y + size, (clear + 1) / 2);
+      if (TEST_FLAG (SQUARECLEARANCEFLAG, pin))
+	{
+		size = (thick + clear + 1) / 2;
+		return StraightRect (pin->X - size, pin->X + size, 
+				     pin->Y - size, pin->Y + size);
+        }
+      else
+	{
+          size = (thick + 1) / 2;
+	  return RoundRect (pin->X - size, pin->X + size, pin->Y - size,
+			    pin->Y + size, (clear + 1) / 2);
+	}
     }
   else
     {
diff --git a/src/polygon1.c b/src/polygon1.c
index 566596d..13b3f1e 100644
--- a/src/polygon1.c
+++ b/src/polygon1.c
@@ -100,8 +100,11 @@ int vect_inters2 (Vector A, Vector B, Vector C, Vector D, Vector S1,
 #undef DEBUG_JUMP
 #undef DEBUG_GATHER
 #undef DEBUG_ANGLE
+#undef DEBUG_INTERSECT
 #undef DEBUG
 #ifdef DEBUG
+#undef NDEBUG
+#include "pcb-printf.h"
 #define DEBUGP(...) pcb_fprintf(stderr, ## __VA_ARGS__)
 #else
 #define DEBUGP(...)
diff --git a/src/strflags.c b/src/strflags.c
index f29da5b..4f302af 100644
--- a/src/strflags.c
+++ b/src/strflags.c
@@ -109,7 +109,8 @@ static FlagBitsType object_flagbits[] = {
   { EDGE2FLAG, N ("edge2"), ALL_TYPES },
   { FULLPOLYFLAG, N ("fullpoly"), POLYGON_TYPE},
   { NOPASTEFLAG, N ("nopaste"), PAD_TYPE },
-  { CONNECTEDFLAG, N ("connected"), ALL_TYPES }
+  { CONNECTEDFLAG, N ("connected"), ALL_TYPES },
+  { SQUARECLEARANCEFLAG, N ("squareclearance"), PIN_TYPES | PAD_TYPE}
 };
 
 static FlagBitsType pcb_flagbits[] = {

--SUOF0GtieIMvvwua--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019