Shiny 3D eye-candy
[geda-pcb/pcjc2.git] / src / drill.c
blobc058712e51160fbeaa407a010c674395cf1e7f1a
1 /*
2 * COPYRIGHT
4 * PCB, interactive printed circuit board design
5 * Copyright (C) 1994,1995,1996 Thomas Nau
7 * This module, drill.c, was written and is Copyright (C) 1997 harry eaton
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * Contact addresses for paper mail and Email:
24 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
25 * Thomas.Nau@rz.uni-ulm.de
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
34 #include "data.h"
35 #include "error.h"
36 #include "mymem.h"
38 #ifdef HAVE_LIBDMALLOC
39 #include <dmalloc.h>
40 #endif
43 * some local prototypes
45 static void FillDrill (DrillType *, ElementType *, PinType *);
46 static void InitializeDrill (DrillType *, PinType *, ElementType *);
49 static void
50 FillDrill (DrillType *Drill, ElementType *Element, PinType *Pin)
52 Cardinal n;
53 ElementType **ptr;
54 PinType **pin;
56 pin = GetDrillPinMemory (Drill);
57 *pin = Pin;
58 if (Element)
60 Drill->PinCount++;
61 for (n = Drill->ElementN - 1; n != -1; n--)
62 if (Drill->Element[n] == Element)
63 break;
64 if (n == -1)
66 ptr = GetDrillElementMemory (Drill);
67 *ptr = Element;
70 else
71 Drill->ViaCount++;
72 if (TEST_FLAG (HOLEFLAG, Pin))
73 Drill->UnplatedCount++;
76 static void
77 InitializeDrill (DrillType *drill, PinType *pin, ElementType *element)
79 void *ptr;
81 drill->DrillSize = pin->DrillingHole;
82 drill->ElementN = 0;
83 drill->ViaCount = 0;
84 drill->PinCount = 0;
85 drill->UnplatedCount = 0;
86 drill->ElementMax = 0;
87 drill->Element = NULL;
88 drill->PinN = 0;
89 drill->Pin = NULL;
90 drill->PinMax = 0;
91 ptr = (void *) GetDrillPinMemory (drill);
92 *((PinType **) ptr) = pin;
93 if (element)
95 ptr = (void *) GetDrillElementMemory (drill);
96 *((ElementType **) ptr) = element;
97 drill->PinCount = 1;
99 else
100 drill->ViaCount = 1;
101 if (TEST_FLAG (HOLEFLAG, pin))
102 drill->UnplatedCount = 1;
105 static int
106 DrillQSort (const void *va, const void *vb)
108 DrillType *a = (DrillType *) va;
109 DrillType *b = (DrillType *) vb;
110 return a->DrillSize - b->DrillSize;
113 DrillInfoType *
114 GetDrillInfo (DataType *top)
116 DrillInfoType *AllDrills;
117 DrillType *Drill = NULL;
118 DrillType savedrill, swapdrill;
119 bool DrillFound = false;
120 bool NewDrill;
122 AllDrills = (DrillInfoType *)calloc (1, sizeof (DrillInfoType));
123 ALLPIN_LOOP (top);
125 if (!DrillFound)
127 DrillFound = true;
128 Drill = GetDrillInfoDrillMemory (AllDrills);
129 InitializeDrill (Drill, pin, element);
131 else
133 if (Drill->DrillSize == pin->DrillingHole)
134 FillDrill (Drill, element, pin);
135 else
137 NewDrill = false;
138 DRILL_LOOP (AllDrills);
140 if (drill->DrillSize == pin->DrillingHole)
142 Drill = drill;
143 FillDrill (Drill, element, pin);
144 break;
146 else if (drill->DrillSize > pin->DrillingHole)
148 if (!NewDrill)
150 NewDrill = true;
151 InitializeDrill (&swapdrill, pin, element);
152 Drill = GetDrillInfoDrillMemory (AllDrills);
153 Drill->DrillSize = pin->DrillingHole + 1;
154 Drill = drill;
156 savedrill = *drill;
157 *drill = swapdrill;
158 swapdrill = savedrill;
161 END_LOOP;
162 if (AllDrills->Drill[AllDrills->DrillN - 1].DrillSize <
163 pin->DrillingHole)
165 Drill = GetDrillInfoDrillMemory (AllDrills);
166 InitializeDrill (Drill, pin, element);
171 ENDALL_LOOP;
172 VIA_LOOP (top);
174 if (!DrillFound)
176 DrillFound = true;
177 Drill = GetDrillInfoDrillMemory (AllDrills);
178 Drill->DrillSize = via->DrillingHole;
179 FillDrill (Drill, NULL, via);
181 else
183 if (Drill->DrillSize != via->DrillingHole)
185 DRILL_LOOP (AllDrills);
187 if (drill->DrillSize == via->DrillingHole)
189 Drill = drill;
190 FillDrill (Drill, NULL, via);
191 break;
194 END_LOOP;
195 if (Drill->DrillSize != via->DrillingHole)
197 Drill = GetDrillInfoDrillMemory (AllDrills);
198 Drill->DrillSize = via->DrillingHole;
199 FillDrill (Drill, NULL, via);
202 else
203 FillDrill (Drill, NULL, via);
206 END_LOOP;
207 qsort (AllDrills->Drill, AllDrills->DrillN, sizeof (DrillType), DrillQSort);
208 return (AllDrills);
211 #define ROUND(x,n) ((int)(((x)+(n)/2)/(n))*(n))
214 Currently unused. Was used in ReportDrills() in report.c and in PrintFab()
215 in print.c (generation of the Gerber fab file), but not when generating the
216 actual CNC files, so the number of drills in the drill report and in the
217 CNC file could differ. This was confusing.
219 #if 0
221 \brief Join similar sized drill sets.
223 \param d Set of all drills to look at, in subsets for each drill size.
225 \param roundto Rounding error. Drills differing less than this value are
226 considered to be of the pame size and joined into a common set.
228 \note In case of hits the number of drill sets changes, so the number of
229 distinct drill sizes changes as well. This can be confusing if
230 RoundDisplayInfo() is used for one kind of display/output, but not for others.
232 void
233 RoundDrillInfo (DrillInfoType *d, int roundto)
235 unsigned int i = 0;
237 /* round in the case with only one drill, too */
238 if (d->DrillN == 1) {
239 d->Drill[0].DrillSize = ROUND (d->Drill[0].DrillSize, roundto);
242 while ((d->DrillN > 0) && (i < d->DrillN - 1))
244 int diam1 = ROUND (d->Drill[i].DrillSize, roundto);
245 int diam2 = ROUND (d->Drill[i + 1].DrillSize, roundto);
247 if (diam1 == diam2)
249 int ei, ej;
251 d->Drill[i].ElementMax
252 = d->Drill[i].ElementN + d->Drill[i+1].ElementN;
253 if (d->Drill[i].ElementMax)
255 d->Drill[i].Element = (ElementType **)realloc (d->Drill[i].Element,
256 d->Drill[i].ElementMax *
257 sizeof (ElementType *));
259 for (ei = 0; ei < d->Drill[i+1].ElementN; ei++)
261 for (ej = 0; ej < d->Drill[i].ElementN; ej++)
262 if (d->Drill[i].Element[ej] == d->Drill[i + 1].Element[ei])
263 break;
264 if (ej == d->Drill[i].ElementN)
265 d->Drill[i].Element[d->Drill[i].ElementN++]
266 = d->Drill[i + 1].Element[ei];
269 free (d->Drill[i + 1].Element);
270 d->Drill[i + 1].Element = NULL;
272 d->Drill[i].PinMax = d->Drill[i].PinN + d->Drill[i + 1].PinN;
273 d->Drill[i].Pin = (PinType **)realloc (d->Drill[i].Pin,
274 d->Drill[i].PinMax *
275 sizeof (PinType *));
276 memcpy (d->Drill[i].Pin + d->Drill[i].PinN, d->Drill[i + 1].Pin,
277 d->Drill[i + 1].PinN * sizeof (PinType *));
278 d->Drill[i].PinN += d->Drill[i + 1].PinN;
279 free (d->Drill[i + 1].Pin);
280 d->Drill[i + 1].Pin = NULL;
282 d->Drill[i].PinCount += d->Drill[i + 1].PinCount;
283 d->Drill[i].ViaCount += d->Drill[i + 1].ViaCount;
284 d->Drill[i].UnplatedCount += d->Drill[i + 1].UnplatedCount;
286 d->Drill[i].DrillSize = diam1;
288 memmove (d->Drill + i + 1,
289 d->Drill + i + 2,
290 (d->DrillN - i - 2) * sizeof (DrillType));
291 d->DrillN--;
293 else
295 d->Drill[i].DrillSize = diam1;
296 i++;
300 #endif
302 void
303 FreeDrillInfo (DrillInfoType *Drills)
305 DRILL_LOOP (Drills);
307 free (drill->Element);
308 free (drill->Pin);
310 END_LOOP;
311 free (Drills->Drill);
312 free (Drills);