pcb 4.1.1
An interactive printed circuit board layout editor.

drill.c

Go to the documentation of this file.
00001 
00035 #ifdef HAVE_CONFIG_H
00036 #include "config.h"
00037 #endif
00038 
00039 #include "data.h"
00040 #include "error.h"
00041 #include "mymem.h"
00042 
00043 #ifdef HAVE_LIBDMALLOC
00044 #include <dmalloc.h>
00045 #endif
00046 
00047 /*
00048  * some local prototypes
00049  */
00050 static void FillDrill (DrillType *, ElementType *, PinType *);
00051 static void InitializeDrill (DrillType *, PinType *, ElementType *);
00052 
00053 
00054 static void
00055 FillDrill (DrillType *Drill, ElementType *Element, PinType *Pin)
00056 {
00057   Cardinal n;
00058   ElementType **ptr;
00059   PinType **pin;
00060 
00061   pin = GetDrillPinMemory (Drill);
00062   *pin = Pin;
00063   if (Element)
00064     {
00065       Drill->PinCount++;
00066       for (n = Drill->ElementN - 1; n != -1; n--)
00067         if (Drill->Element[n] == Element)
00068           break;
00069       if (n == -1)
00070         {
00071           ptr = GetDrillElementMemory (Drill);
00072           *ptr = Element;
00073         }
00074     }
00075   else
00076     Drill->ViaCount++;
00077   if (TEST_FLAG (HOLEFLAG, Pin))
00078     Drill->UnplatedCount++;
00079 }
00080 
00081 static void
00082 InitializeDrill (DrillType *drill, PinType *pin, ElementType *element)
00083 {
00084   void *ptr;
00085 
00086   drill->DrillSize = pin->DrillingHole;
00087   drill->ElementN = 0;
00088   drill->ViaCount = 0;
00089   drill->PinCount = 0;
00090   drill->UnplatedCount = 0;
00091   drill->ElementMax = 0;
00092   drill->Element = NULL;
00093   drill->PinN = 0;
00094   drill->Pin = NULL;
00095   drill->PinMax = 0;
00096   ptr = (void *) GetDrillPinMemory (drill);
00097   *((PinType **) ptr) = pin;
00098   if (element)
00099     {
00100       ptr = (void *) GetDrillElementMemory (drill);
00101       *((ElementType **) ptr) = element;
00102       drill->PinCount = 1;
00103     }
00104   else
00105     drill->ViaCount = 1;
00106   if (TEST_FLAG (HOLEFLAG, pin))
00107     drill->UnplatedCount = 1;
00108 }
00109 
00110 static int
00111 DrillQSort (const void *va, const void *vb)
00112 {
00113   DrillType *a = (DrillType *) va;
00114   DrillType *b = (DrillType *) vb;
00115   return a->DrillSize - b->DrillSize;
00116 }
00117 
00118 DrillInfoType *
00119 GetDrillInfo (DataType *top)
00120 {
00121   DrillInfoType *AllDrills;
00122   DrillType *Drill = NULL;
00123   DrillType savedrill, swapdrill;
00124   bool DrillFound = false;
00125   bool NewDrill;
00126 
00127   AllDrills = (DrillInfoType *)calloc (1, sizeof (DrillInfoType));
00128   ALLPIN_LOOP (top);
00129   {
00130     if (!DrillFound)
00131       {
00132         DrillFound = true;
00133         Drill = GetDrillInfoDrillMemory (AllDrills);
00134         InitializeDrill (Drill, pin, element);
00135       }
00136     else
00137       {
00138         if (Drill->DrillSize == pin->DrillingHole)
00139           FillDrill (Drill, element, pin);
00140         else
00141           {
00142             NewDrill = false;
00143             DRILL_LOOP (AllDrills);
00144             {
00145               if (drill->DrillSize == pin->DrillingHole)
00146                 {
00147                   Drill = drill;
00148                   FillDrill (Drill, element, pin);
00149                   break;
00150                 }
00151               else if (drill->DrillSize > pin->DrillingHole)
00152                 {
00153                   if (!NewDrill)
00154                     {
00155                       NewDrill = true;
00156                       InitializeDrill (&swapdrill, pin, element);
00157                       Drill = GetDrillInfoDrillMemory (AllDrills);
00158                       Drill->DrillSize = pin->DrillingHole + 1;
00159                       Drill = drill;
00160                     }
00161                   savedrill = *drill;
00162                   *drill = swapdrill;
00163                   swapdrill = savedrill;
00164                 }
00165             }
00166             END_LOOP;
00167             if (AllDrills->Drill[AllDrills->DrillN - 1].DrillSize <
00168                 pin->DrillingHole)
00169               {
00170                 Drill = GetDrillInfoDrillMemory (AllDrills);
00171                 InitializeDrill (Drill, pin, element);
00172               }
00173           }
00174       }
00175   }
00176   ENDALL_LOOP;
00177   VIA_LOOP (top);
00178   {
00179     if (!DrillFound)
00180       {
00181         DrillFound = true;
00182         Drill = GetDrillInfoDrillMemory (AllDrills);
00183         Drill->DrillSize = via->DrillingHole;
00184         FillDrill (Drill, NULL, via);
00185       }
00186     else
00187       {
00188         if (Drill->DrillSize != via->DrillingHole)
00189           {
00190             DRILL_LOOP (AllDrills);
00191             {
00192               if (drill->DrillSize == via->DrillingHole)
00193                 {
00194                   Drill = drill;
00195                   FillDrill (Drill, NULL, via);
00196                   break;
00197                 }
00198             }
00199             END_LOOP;
00200             if (Drill->DrillSize != via->DrillingHole)
00201               {
00202                 Drill = GetDrillInfoDrillMemory (AllDrills);
00203                 Drill->DrillSize = via->DrillingHole;
00204                 FillDrill (Drill, NULL, via);
00205               }
00206           }
00207         else
00208           FillDrill (Drill, NULL, via);
00209       }
00210   }
00211   END_LOOP;
00212   qsort (AllDrills->Drill, AllDrills->DrillN, sizeof (DrillType), DrillQSort);
00213   return (AllDrills);
00214 }
00215 
00216 #define ROUND(x,n) ((int)(((x)+(n)/2)/(n))*(n))
00217 
00218 /*
00219   Currently unused. Was used in ReportDrills() in report.c and in PrintFab()
00220   in print.c (generation of the Gerber fab file), but not when generating the
00221   actual CNC files, so the number of drills in the drill report and in the
00222   CNC file could differ. This was confusing.
00223 */
00224 #if 0
00225 
00237 void
00238 RoundDrillInfo (DrillInfoType *d, int roundto)
00239 {
00240   unsigned int i = 0;
00241 
00242   /* round in the case with only one drill, too */
00243   if (d->DrillN == 1) {
00244     d->Drill[0].DrillSize = ROUND (d->Drill[0].DrillSize, roundto);
00245   }
00246 
00247   while ((d->DrillN > 0) && (i < d->DrillN - 1))
00248     {
00249       int diam1 = ROUND (d->Drill[i].DrillSize, roundto);
00250       int diam2 = ROUND (d->Drill[i + 1].DrillSize, roundto);
00251 
00252       if (diam1 == diam2)
00253         {
00254           int ei, ej;
00255 
00256           d->Drill[i].ElementMax
00257             = d->Drill[i].ElementN + d->Drill[i+1].ElementN;
00258           if (d->Drill[i].ElementMax)
00259             {
00260               d->Drill[i].Element = (ElementType **)realloc (d->Drill[i].Element,
00261                                              d->Drill[i].ElementMax *
00262                                              sizeof (ElementType *));
00263 
00264               for (ei = 0; ei < d->Drill[i+1].ElementN; ei++)
00265                 {
00266                   for (ej = 0; ej < d->Drill[i].ElementN; ej++)
00267                     if (d->Drill[i].Element[ej] == d->Drill[i + 1].Element[ei])
00268                       break;
00269                   if (ej == d->Drill[i].ElementN)
00270                     d->Drill[i].Element[d->Drill[i].ElementN++]
00271                       = d->Drill[i + 1].Element[ei];
00272                 }
00273             }
00274           free (d->Drill[i + 1].Element);
00275           d->Drill[i + 1].Element = NULL;
00276 
00277           d->Drill[i].PinMax = d->Drill[i].PinN + d->Drill[i + 1].PinN;
00278           d->Drill[i].Pin = (PinType **)realloc (d->Drill[i].Pin,
00279                                      d->Drill[i].PinMax *
00280                                      sizeof (PinType *));
00281           memcpy (d->Drill[i].Pin + d->Drill[i].PinN, d->Drill[i + 1].Pin,
00282                   d->Drill[i + 1].PinN * sizeof (PinType *));
00283           d->Drill[i].PinN += d->Drill[i + 1].PinN;
00284           free (d->Drill[i + 1].Pin);
00285           d->Drill[i + 1].Pin = NULL;
00286 
00287           d->Drill[i].PinCount += d->Drill[i + 1].PinCount;
00288           d->Drill[i].ViaCount += d->Drill[i + 1].ViaCount;
00289           d->Drill[i].UnplatedCount += d->Drill[i + 1].UnplatedCount;
00290 
00291           d->Drill[i].DrillSize = diam1;
00292 
00293           memmove (d->Drill + i + 1,
00294                    d->Drill + i + 2,
00295                    (d->DrillN - i - 2) * sizeof (DrillType));
00296           d->DrillN--;
00297         }
00298       else
00299         {
00300           d->Drill[i].DrillSize = diam1;
00301           i++;
00302         }
00303     }
00304 }
00305 #endif
00306 
00307 void
00308 FreeDrillInfo (DrillInfoType *Drills)
00309 {
00310   DRILL_LOOP (Drills);
00311   {
00312     free (drill->Element);
00313     free (drill->Pin);
00314   }
00315   END_LOOP;
00316   free (Drills->Drill);
00317   free (Drills);
00318 }