// same as above method but allows for custom max bond lengths public Dictionary <int, Bond> CalculateBonds(Dictionary <int, Atom> atoms, Dictionary <ElementPair, float> maxBondLengths, int processorCores) { this.atoms = atoms; this.maxBondLengths = maxBondLengths; bonds = new Dictionary <int, Bond>(); tree = new KdTree <float, int>(3, new FloatMath()); addedBonds = new HashSet <string>(); bondID = 0; UnityEngine.Debug.Log("Generating Atom Tree"); Stopwatch watch = new Stopwatch(); watch.Start(); foreach (KeyValuePair <int, Atom> atom in atoms) { tree.Add(new float[] { atom.Value.Position.x, atom.Value.Position.y, atom.Value.Position.z }, atom.Key); } watch.Stop(); UnityEngine.Debug.Log("Generated Atom Tree: " + watch.ElapsedMilliseconds.ToString("N2")); watch.Reset(); watch.Start(); //for each atom find all linked atoms List <Thread> threadList = new List <Thread>(); List <int> atomIndexes = atoms.Keys.ToList(); int threadCount = processorCores - 1; if (threadCount <= 0) { threadCount = 1; } int maxAtomsPerThread = Mathf.Max(1, atomIndexes.Count / threadCount); for (int i = 0; i < atomIndexes.Count; i += maxAtomsPerThread) { int threadAtomCount = maxAtomsPerThread; if (i > atomIndexes.Count - threadAtomCount - 1) { threadAtomCount = atomIndexes.Count - i - 1; } List <int> threadAtoms = atomIndexes.GetRange(i, threadAtomCount); Thread newThread = new Thread(findBonds); newThread.Start(threadAtoms); threadList.Add(newThread); } foreach (var thread in threadList) { thread.Join(); } watch.Stop(); UnityEngine.Debug.Log("Generated Bond Results: " + watch.ElapsedMilliseconds.ToString("N2")); watch.Reset(); return(bonds.ToDictionary(entry => entry.Key, entry => entry.Value)); }