Introduce POLYGONHOLE_MODE for creating holes in polygons
[geda-pcb/gde.git] / src / drill.c
blob738ed18f989c5a7bb567d81bda26bf06c01b3175
1 /* $Id$ */
3 /*
4 * COPYRIGHT
6 * PCB, interactive printed circuit board design
7 * Copyright (C) 1994,1995,1996 Thomas Nau
9 * This module, drill.c, was written and is Copyright (C) 1997 harry eaton
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 * Contact addresses for paper mail and Email:
26 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
27 * Thomas.Nau@rz.uni-ulm.de
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
36 #include "data.h"
37 #include "error.h"
38 #include "mymem.h"
40 #ifdef HAVE_LIBDMALLOC
41 #include <dmalloc.h>
42 #endif
44 RCSID ("$Id$");
50 * some local prototypes
52 static void FillDrill (DrillTypePtr, ElementTypePtr, PinTypePtr);
53 static void InitializeDrill (DrillTypePtr, PinTypePtr, ElementTypePtr);
56 static void
57 FillDrill (DrillTypePtr Drill, ElementTypePtr Element, PinTypePtr Pin)
59 Cardinal n;
60 ElementTypeHandle ptr;
61 PinTypeHandle pin;
63 pin = GetDrillPinMemory (Drill);
64 *pin = Pin;
65 if (Element)
67 Drill->PinCount++;
68 for (n = Drill->ElementN - 1; n != -1; n--)
69 if (Drill->Element[n] == Element)
70 break;
71 if (n == -1)
73 ptr = GetDrillElementMemory (Drill);
74 *ptr = Element;
77 else
78 Drill->ViaCount++;
79 if (TEST_FLAG (HOLEFLAG, Pin))
80 Drill->UnplatedCount++;
83 static void
84 InitializeDrill (DrillTypePtr drill, PinTypePtr pin, ElementTypePtr element)
86 void *ptr;
88 drill->DrillSize = pin->DrillingHole;
89 drill->ElementN = 0;
90 drill->ViaCount = 0;
91 drill->PinCount = 0;
92 drill->UnplatedCount = 0;
93 drill->ElementMax = 0;
94 drill->Element = NULL;
95 drill->PinN = 0;
96 drill->Pin = NULL;
97 drill->PinMax = 0;
98 ptr = (void *) GetDrillPinMemory (drill);
99 *((PinTypeHandle) ptr) = pin;
100 if (element)
102 ptr = (void *) GetDrillElementMemory (drill);
103 *((ElementTypeHandle) ptr) = element;
104 drill->PinCount = 1;
106 else
107 drill->ViaCount = 1;
108 if (TEST_FLAG (HOLEFLAG, pin))
109 drill->UnplatedCount = 1;
112 static int
113 DrillQSort (const void *va, const void *vb)
115 DrillType *a = (DrillType *) va;
116 DrillType *b = (DrillType *) vb;
117 return a->DrillSize - b->DrillSize;
120 DrillInfoTypePtr
121 GetDrillInfo (DataTypePtr top)
123 DrillInfoTypePtr AllDrills;
124 DrillTypePtr Drill = NULL;
125 DrillType savedrill, swapdrill;
126 bool DrillFound = false;
127 bool NewDrill;
129 AllDrills = MyCalloc (1, sizeof (DrillInfoType), "GetAllDrillInfo()");
130 ALLPIN_LOOP (top);
132 if (!DrillFound)
134 DrillFound = true;
135 Drill = GetDrillInfoDrillMemory (AllDrills);
136 InitializeDrill (Drill, pin, element);
138 else
140 if (Drill->DrillSize == pin->DrillingHole)
141 FillDrill (Drill, element, pin);
142 else
144 NewDrill = false;
145 DRILL_LOOP (AllDrills);
147 if (drill->DrillSize == pin->DrillingHole)
149 Drill = drill;
150 FillDrill (Drill, element, pin);
151 break;
153 else if (drill->DrillSize > pin->DrillingHole)
155 if (!NewDrill)
157 NewDrill = true;
158 InitializeDrill (&swapdrill, pin, element);
159 Drill = GetDrillInfoDrillMemory (AllDrills);
160 Drill->DrillSize = pin->DrillingHole + 1;
161 Drill = drill;
163 savedrill = *drill;
164 *drill = swapdrill;
165 swapdrill = savedrill;
168 END_LOOP;
169 if (AllDrills->Drill[AllDrills->DrillN - 1].DrillSize <
170 pin->DrillingHole)
172 Drill = GetDrillInfoDrillMemory (AllDrills);
173 InitializeDrill (Drill, pin, element);
178 ENDALL_LOOP;
179 VIA_LOOP (top);
181 if (!DrillFound)
183 DrillFound = true;
184 Drill = GetDrillInfoDrillMemory (AllDrills);
185 Drill->DrillSize = via->DrillingHole;
186 FillDrill (Drill, NULL, via);
188 else
190 if (Drill->DrillSize != via->DrillingHole)
192 DRILL_LOOP (AllDrills);
194 if (drill->DrillSize == via->DrillingHole)
196 Drill = drill;
197 FillDrill (Drill, NULL, via);
198 break;
201 END_LOOP;
202 if (Drill->DrillSize != via->DrillingHole)
204 Drill = GetDrillInfoDrillMemory (AllDrills);
205 Drill->DrillSize = via->DrillingHole;
206 FillDrill (Drill, NULL, via);
209 else
210 FillDrill (Drill, NULL, via);
213 END_LOOP;
214 qsort (AllDrills->Drill, AllDrills->DrillN, sizeof (DrillType), DrillQSort);
215 return (AllDrills);
218 #define ROUND(x,n) ((int)(((x)+(n)/2)/(n))*(n))
220 void
221 RoundDrillInfo (DrillInfoTypePtr d, int roundto)
223 unsigned int i = 0;
225 while ((d->DrillN > 0) && (i < d->DrillN - 1))
227 int diam1 = ROUND (d->Drill[i].DrillSize, roundto);
228 int diam2 = ROUND (d->Drill[i + 1].DrillSize, roundto);
230 if (diam1 == diam2)
232 int ei, ej;
234 d->Drill[i].ElementMax
235 = d->Drill[i].ElementN + d->Drill[i+1].ElementN;
236 if (d->Drill[i].ElementMax)
238 d->Drill[i].Element = MyRealloc (d->Drill[i].Element,
239 d->Drill[i].ElementMax *
240 sizeof(ElementTypePtr),
241 "RoundDrillInfo");
243 for (ei = 0; ei < d->Drill[i+1].ElementN; ei++)
245 for (ej = 0; ej < d->Drill[i].ElementN; ej++)
246 if (d->Drill[i].Element[ej] == d->Drill[i + 1].Element[ei])
247 break;
248 if (ej == d->Drill[i].ElementN)
249 d->Drill[i].Element[d->Drill[i].ElementN++]
250 = d->Drill[i + 1].Element[ei];
253 MYFREE (d->Drill[i + 1].Element);
255 d->Drill[i].PinMax = d->Drill[i].PinN + d->Drill[i + 1].PinN;
256 d->Drill[i].Pin = MyRealloc (d->Drill[i].Pin,
257 d->Drill[i].PinMax *
258 sizeof (PinTypePtr), "RoundDrillInfo");
259 memcpy (d->Drill[i].Pin + d->Drill[i].PinN, d->Drill[i + 1].Pin,
260 d->Drill[i + 1].PinN * sizeof (PinTypePtr));
261 d->Drill[i].PinN += d->Drill[i + 1].PinN;
262 MYFREE (d->Drill[i + 1].Pin);
264 d->Drill[i].PinCount += d->Drill[i + 1].PinCount;
265 d->Drill[i].ViaCount += d->Drill[i + 1].ViaCount;
266 d->Drill[i].UnplatedCount += d->Drill[i + 1].UnplatedCount;
268 d->Drill[i].DrillSize = diam1;
270 memmove (d->Drill + i + 1,
271 d->Drill + i + 2,
272 (d->DrillN - i - 2) * sizeof (DrillType));
273 d->DrillN--;
275 else
277 d->Drill[i].DrillSize = diam1;
278 i++;
283 void
284 FreeDrillInfo (DrillInfoTypePtr Drills)
286 DRILL_LOOP (Drills);
288 MYFREE (drill->Element);
289 MYFREE (drill->Pin);
291 END_LOOP;
292 MYFREE (Drills->Drill);
293 SaveFree (Drills);