/* --------------------------------------------------------------------------- * Auto-place selected components. */ bool AutoPlaceSelected (void) { NetListType *Nets; PointerListType Selected = { 0, 0, NULL }; PerturbationType pt; double C0, T0; bool changed = false; /* (initial netlist processing copied from AddAllRats) */ /* the netlist library has the text form * ProcNetlist fills in the Netlist * structure the way the final routing * is supposed to look */ Nets = ProcNetlist (&PCB->NetlistLib); if (!Nets) { Message (_("Can't add rat lines because no netlist is loaded.\n")); goto done; } Selected = collectSelectedElements (); if (Selected.PtrN == 0) { Message (_("No elements selected to autoplace.\n")); goto done; } /* simulated annealing */ { /* compute T0 by doing a random series of moves. */ const int TRIALS = 10; const double Tx = MIL_TO_COORD (300), P = 0.95; double Cs = 0.0; int i; C0 = ComputeCost (Nets, Tx, Tx); for (i = 0; i < TRIALS; i++) { pt = createPerturbation (&Selected, INCH_TO_COORD (1)); doPerturb (&pt, false); Cs += fabs (ComputeCost (Nets, Tx, Tx) - C0); doPerturb (&pt, true); } T0 = -(Cs / TRIALS) / log (P); printf ("Initial T: %f\n", T0); } /* now anneal in earnest */ { double T = T0; long steps = 0; int good_moves = 0, moves = 0; const int good_move_cutoff = CostParameter.m * Selected.PtrN; const int move_cutoff = 2 * good_move_cutoff; printf ("Starting cost is %.0f\n", ComputeCost (Nets, T0, 5)); C0 = ComputeCost (Nets, T0, T); while (1) { double Cprime; pt = createPerturbation (&Selected, T); doPerturb (&pt, false); Cprime = ComputeCost (Nets, T0, T); if (Cprime < C0) { /* good move! */ C0 = Cprime; good_moves++; steps++; } else if ((random () / (double) RAND_MAX) < exp (MIN (MAX (-20, (C0 - Cprime) / T), 20))) { /* not good but keep it anyway */ C0 = Cprime; steps++; } else doPerturb (&pt, true); /* undo last change */ moves++; /* are we at the end of a stage? */ if (good_moves >= good_move_cutoff || moves >= move_cutoff) { printf ("END OF STAGE: COST %.0f\t" "GOOD_MOVES %d\tMOVES %d\t" "T: %.1f\n", C0, good_moves, moves, T); /* is this the end? */ if (T < 5 || good_moves < moves / CostParameter.good_ratio) break; /* nope, adjust T and continue */ moves = good_moves = 0; T *= CostParameter.gamma; /* cost is T dependent, so recompute */ C0 = ComputeCost (Nets, T0, T); } } changed = (steps > 0); } done: if (changed) { DeleteRats (false); AddAllRats (false, NULL); Redraw (); } FreePointerListMemory (&Selected); return (changed); }
int ActionLoadVendorFrom (int argc, char **argv, Coord x, Coord y) { int i; char *fname = NULL; static char *default_file = NULL; char *sval; Resource *res, *drcres, *drlres; int type; bool free_fname = false; cached_drill = -1; fname = argc ? argv[0] : 0; if (!fname || !*fname) { fname = gui->fileselect (_("Load Vendor Resource File..."), _("Picks a vendor resource file to load.\n" "This file can contain drc settings for a\n" "particular vendor as well as a list of\n" "predefined drills which are allowed."), default_file, ".res", "vendor", HID_FILESELECT_READ); if (fname == NULL) AFAIL (load_vendor); free_fname = true; free (default_file); default_file = NULL; if (fname && *fname) default_file = strdup (fname); } /* Unload any vendor table we may have had */ n_vendor_drills = 0; n_refdes = 0; n_value = 0; n_descr = 0; FREE (vendor_drills); FREE (ignore_refdes); FREE (ignore_value); FREE (ignore_descr); /* load the resource file */ res = resource_parse (fname, NULL); if (res == NULL) { Message (_("Could not load vendor resource file \"%s\"\n"), fname); return 1; } /* figure out the vendor name, if specified */ vendor_name = (char *)UNKNOWN (resource_value (res, "vendor")); /* figure out the units, if specified */ sval = resource_value (res, "units"); if (sval == NULL) { sf = MIL_TO_COORD(1); } else if ((NSTRCMP (sval, "mil") == 0) || (NSTRCMP (sval, "mils") == 0)) { sf = MIL_TO_COORD(1); } else if ((NSTRCMP (sval, "inch") == 0) || (NSTRCMP (sval, "inches") == 0)) { sf = INCH_TO_COORD(1); } else if (NSTRCMP (sval, "mm") == 0) { sf = MM_TO_COORD(1); } else { Message ("\"%s\" is not a supported units. Defaulting to inch\n", sval); sf = INCH_TO_COORD(1); } /* default to ROUND_UP */ rounding_method = ROUND_UP; /* extract the drillmap resource */ drlres = resource_subres (res, "drillmap"); if (drlres == NULL) { Message (_("No drillmap resource found\n")); } else { sval = resource_value (drlres, "round"); if (sval != NULL) { if (NSTRCMP (sval, "up") == 0) { rounding_method = ROUND_UP; } else if (NSTRCMP (sval, "nearest") == 0) { rounding_method = CLOSEST; } else { Message (_ ("\"%s\" is not a valid rounding type. Defaulting to up\n"), sval); rounding_method = ROUND_UP; } } process_skips (resource_subres (drlres, "skips")); for (i = 0; i < drlres->c; i++) { type = resource_type (drlres->v[i]); switch (type) { case 10: /* just a number */ add_to_drills (drlres->v[i].value); break; default: break; } } } /* Extract the DRC resource */ drcres = resource_subres (res, "drc"); sval = resource_value (drcres, "copper_space"); if (sval != NULL) { PCB->Bloat = floor (sf * atof (sval) + 0.5); Message (_("Set DRC minimum copper spacing to %.2f mils\n"), 0.01 * PCB->Bloat); } sval = resource_value (drcres, "copper_overlap"); if (sval != NULL) { PCB->Shrink = floor (sf * atof (sval) + 0.5); Message (_("Set DRC minimum copper overlap to %.2f mils\n"), 0.01 * PCB->Shrink); } sval = resource_value (drcres, "copper_width"); if (sval != NULL) { PCB->minWid = floor (sf * atof (sval) + 0.5); Message (_("Set DRC minimum copper spacing to %.2f mils\n"), 0.01 * PCB->minWid); } sval = resource_value (drcres, "silk_width"); if (sval != NULL) { PCB->minSlk = floor (sf * atof (sval) + 0.5); Message (_("Set DRC minimum silk width to %.2f mils\n"), 0.01 * PCB->minSlk); } sval = resource_value (drcres, "min_drill"); if (sval != NULL) { PCB->minDrill = floor (sf * atof (sval) + 0.5); Message (_("Set DRC minimum drill diameter to %.2f mils\n"), 0.01 * PCB->minDrill); } sval = resource_value (drcres, "min_ring"); if (sval != NULL) { PCB->minRing = floor (sf * atof (sval) + 0.5); Message (_("Set DRC minimum annular ring to %.2f mils\n"), 0.01 * PCB->minRing); } Message (_("Loaded %d vendor drills from %s\n"), n_vendor_drills, fname); Message (_("Loaded %d RefDes skips, %d Value skips, %d Descr skips\n"), n_refdes, n_value, n_descr); vendorMapEnable = true; apply_vendor_map (); if (free_fname) free (fname); return 0; }