public override IEnumerable <PenDrawingPath> generate()
        {
            CMDProcessPool pool = new CMDProcessPool(generatorConfig.MaxTSPThreads);

            TSPLibProblem[] tsps = new TSPLibProblem[pointSets.Count];

            //
            // foreach list of points
            // make a tsp problem.
            // add it to the LKH job pool if no output file exists
            //
            for (int i = 0; i < pointSets.Count; ++i)
            {
                TSPLibProblem tsp = TSPLibProblem.FromPoints(pointSets[i].GetEnumerator(), BaseFileName + "." + i);
                if (!tsp.OutputFileExists())
                {
                    pool.Add(tsp.GetTSPCommand());
                }
                tsps[i] = tsp;
            }

            pool.run();

            // Output files should now exists for all tsp problems
            // create pen drawing paths from each of them
            for (int i = 0; i < pointSets.Count; ++i)
            {
                yield return(fromTSP(tsps[i], pointSets[i]));
            }
        }
Example #2
0
        public static TSPLibProblem FromPoints(IEnumerator <Vector2f> points, string IndicesInOutFileName, float multiplier = 100f)
        {
            TSPLibProblem tsp = new TSPLibProblem(IndicesInOutFileName);

            tsp.multiplier = multiplier;

            StringBuilder eucPoints = new StringBuilder();

            while (points.MoveNext())
            {
                Vector2f scaled = points.Current * tsp.multiplier;
                eucPoints.Append(string.Format("{0} {1} {2}\n", ++tsp.length, (int)scaled.x, (int)scaled.y));
            }
            tsp.problemFileStr = string.Format(ProblemFormat, tsp.length, eucPoints.ToString());
            tsp.WriteParamAndProbWithBaseName(tsp.IndicesInOutFileBaseName);
            return(tsp);
        }
        PenDrawingPath fromTSP(TSPLibProblem tsp, List <Vector2f> points)
        {
            PenDrawingPath pdpath = new PenDrawingPath();

            bool success = tsp.setIndicesFromOutputFile();

            Debug.Log("TSP success? " + success);
            if (success)
            {
                for (int i = 0; i < points.Count; ++i)
                {
                    pdpath.addDrawMove(points[tsp.indexAt(i)] * viewBoxToPaperScale);
                }
            }
            else
            {
                Debug.LogWarning("tsp encountered an error");
            }
            Debug.Log("after add pts ");
            return(pdpath);
        }
        void SolveTriTree(PenDrawingPath pdPath)
        {
            //CONSIDER: two passes
            // 1.) Dark very detailed
            // 2.) mid to light don't sweat the details as much

            //split tri tree leaves if not sufficiently populated
            if (generatorConfig.ShouldSplitUnderFilledTris)
            {
                triTree.root.SplitUnderPopulatedLeaves(generatorConfig.TriFilledThreshold, generatorConfig.MaxSplitToFillRecursionDepth);
            }

            triTree.root.CullDataWithMaxMean(bitMapPointGenerator.MaxGrayScale);

            List <IsoTriangle <PixelTriData> > subTrees;

            // split tree into max cities sub trees
            subTrees = triTree.root.NonEmptyChildrenWithMaxLeaves(generatorConfig.MaxTSPTriangleCities);



            //DEBUG
            var meshGO = MeshUtil.MakeGameObject(triTree.getMesh(), "CrosshatchTriTree");

            var pool      = new CMDProcessPool(generatorConfig.MaxTSPThreads);
            var subLeaves = new List <IsoTriangle <PixelTriData> > [subTrees.Count];
            var tsps      = new TSPLibProblem[subTrees.Count];

            //DEBUG delete any previously generated files
            TSPLibProblem.GetDeleteAllCommand(BaseFileName + "*").ToCMDProcess().run();

            for (int i = 0; i < subTrees.Count; ++i)
            {
                var tree = subTrees[i];

                //get leaf centers
                var leaves = tree.GetLeaves(true);

                var centers = new List <Vector2f>(leaves.Count);

                for (int j = 0; j < leaves.Count; ++j)
                {
                    centers.Add(leaves[j].center);
                }

                // solve each sub tree
                var tsp = TSPLibProblem.FromPoints(centers.GetEnumerator(), BaseFileName + ".tri." + i);
                if (!tsp.OutputFileExists())
                {
                    pool.Add(tsp.GetTSPCommand());
                }

                subLeaves[i] = leaves;
                tsps[i]      = tsp;
            }
            pool.run();

            for (int i = 0; i < subTrees.Count; ++i)
            {
                // crosshatch sub trees
                var tsp = tsps[i];
                if (!tsp.setIndicesFromOutputFile())
                {
                    Debug.LogWarning("no tsp indices");
                    continue; //TODO: handle more gracefully
                }
                var leaves = subLeaves[i];

                TriCrosshatch <PixelTriData> tch = null, last = null;

                for (int j = 0; j < leaves.Count; ++j)
                {
                    tch      = new TriCrosshatch <PixelTriData>(this, leaves[tsp.indexAt(j)]);
                    tch.last = last;
                    tch.next = j == leaves.Count - 1 ? null : new TriCrosshatch <PixelTriData>(this, leaves[tsp.indexAt(j + 1)]);

                    tch.AddDrawPoints(pdPath, viewBoxToPaperScale, (float)machineConfig.toolDiameterMM);

                    last = tch;
                }
            }
        }