コード例 #1
0
        private PenDrawingPath pathForBoxDBUG(Box2f box)
        {
            PenDrawingPath pp = new PenDrawingPath();

            pp.Add(new PenMove()
            {
                destination = box.min * viewBoxToPaperScale, color = Color.red
            });
            pp.Add(new PenMove()
            {
                destination = box.lowerRight * viewBoxToPaperScale
            });
            pp.Add(new PenMove()
            {
                destination = box.max * viewBoxToPaperScale
            });
            pp.Add(new PenMove()
            {
                destination = box.upperLeft * viewBoxToPaperScale
            });
            pp.Add(new PenMove()
            {
                destination = box.min * viewBoxToPaperScale, color = Color.black
            });
            return(pp);
        }
コード例 #2
0
            void FillTri(PenDrawingPath pdPath, float imageToPaperScale, float toolDiam)
            {
                //TODO: add some notion of pixel to pen diameter?

                float dark = Mathf.Clamp(.01f, .999f, (float)tri.onlineNormalEstimator.mean() * (1f - tri.Filled));

                Vector2f closest, a, b;

                tri.ClosestPoint(entryPoint, out closest, out a, out b);

                closest *= imageToPaperScale; a *= imageToPaperScale; b *= imageToPaperScale;

                Vector2f dA = a - closest, dB = b - closest;

                float length = tri.dims.x * imageToPaperScale;
                float incr   = toolDiam + 5f * toolDiam * dark; //  length * dark;

                incr = Mathf.Max(toolDiam, incr);

                int zigs = (int)(length / incr);

                Vector2f m, n;

                for (int i = 0; i < zigs * 2; i += 2)
                {
                    m = dA * i / (float)zigs;
                    pdPath.addDrawMove(closest + m);
                    n = dB * (i + 1) / (float)zigs;
                    pdPath.addDrawMove(closest + n);
                }

                // move to exit
                pdPath.addDrawMove(exitPoint * imageToPaperScale);
            }
コード例 #3
0
        public override IEnumerable <PenDrawingPath> generate()
        {
            PenDrawingPath pdPath = new PenDrawingPath();

            SolveTriTree(pdPath);
            //DoTestTris(pdPath);

            yield return(pdPath);
        }
コード例 #4
0
        private PenDrawingPath twoPointPenPath(Vector2f start, Vector2f end, Matrix2f rot, Color c)
        {
            PenDrawingPath pp = new PenDrawingPath();

            pp.addDownUpDrawMove((rot * start) * viewBoxToPaperScale, (rot * end) * viewBoxToPaperScale, c);
            //pp.Add(new PenMove() { destination = (rot * start) * viewBoxToPaperScale, up = false, color = c });
            //pp.Add(new PenMove() { destination = (rot * end) * viewBoxToPaperScale, up = true });
            return(pp);
        }
コード例 #5
0
ファイル: SCPen.cs プロジェクト: melsov/SVGCrosshatch
        public void makeMoves(PenDrawingPath path)
        {
            PenUpdate pu = new PenUpdate(path);

            foreach (var sub in subscribers)
            {
                sub(pu);
            }

            //foreach(PenMove iter in path.GetMoves()) {
            //    setPosition(iter);
            //}
        }
コード例 #6
0
            public void AddDrawPoints(PenDrawingPath pdPath, float imageBoxToPaperScale, float toolDiam)
            {
                var borders = tri.Border();

                ientry     = 0; iexit = 1;
                exitPoint  = borders[1];
                entryPoint = borders[0];
                bool touchingLast = false;

                if (last != null)
                {
                    touchingLast = last.adjacentExitPoint;
                    if (touchingLast)
                    {
                        entryPoint = last.exitPoint;
                    }
                    ientry = tri.ClosestBorderIndex(last.exitPoint);
                }

                if (next != null)
                {
                    Vector2f _exit;
                    if (tri.IsTouching(next.tri, out _exit))
                    {
                        adjacentExitPoint = true;
                        exitPoint         = _exit;
                        iexit             = tri.ClosestBorderIndex(_exit);
                    }
                }


                if (!touchingLast)
                {
                    pdPath.addTravelMove(entryPoint * imageBoxToPaperScale, ColorUtil.fuschia);
                }

                //if (tri.dims.x < toolDiam)
                //{
                //    pdPath.addDrawMove(tri.center * imageBoxToPaperScale);
                //}
                //else
                {
                    //FillTri(pdPath, imageBoxToPaperScale, toolDiam);
                    //TraceTri(pdPath, imageBoxToPaperScale, toolDiam);
                    DrawTriSpiral(pdPath, ientry, iexit);
                }
                // CONSIDER: fill tris based on grayscale and populatedness
                // keep track of spread-out-ness of data within tris?
            }
コード例 #7
0
        void DoTestTris(PenDrawingPath pdPath)
        {
            Vector2f off  = Vector2f.One * 4f;
            float    size = 40f;

            DebugDrawTestTri(
                pdPath,
                off + Vector2f.Zero,
                0,
                1,
                size: size,
                dark: .1f,
                inverted: false);
            DebugDrawTestTri(
                pdPath,
                off + Vector2f.AxisX * (size * 1.05f),
                2,
                0,
                size: size,
                dark: .2f,
                inverted: false);

            DebugDrawTestTri(
                pdPath,
                off + Vector2f.AxisX * (size * 1.05f * .5f) + Vector2f.AxisY * size,
                0,
                0,
                size: size,
                dark: .3f,
                inverted: true);
            DebugDrawTestTri(
                pdPath,
                off + Vector2f.AxisX * (size * 1.05f * .5f) + Vector2f.AxisY * size,
                0,
                0,
                size: size,
                dark: .4f,
                inverted: false);
            DebugDrawTestTri(
                pdPath,
                off + Vector2f.AxisX * (size * 3.0125f * .5f) + Vector2f.AxisY * size,
                0,
                0,
                size: size,
                dark: .5f,
                inverted: false);
        }
コード例 #8
0
        public override IEnumerable <PenDrawingPath> generate()
        {
            if (pointSets != null)
            {
                for (int i = 0; i < pointSets.Count; ++i)
                {
                    PenDrawingPath pdPath = new PenDrawingPath();
                    var            points = pointSets[i];
                    foreach (var p in points)
                    {
                        pdPath.addDrawMove(p * viewBoxToPaperScale);
                    }

                    yield return(pdPath);
                }
            }
        }
コード例 #9
0
        void DebugDrawTestTri(PenDrawingPath pdPath, Vector2f offset, int ientry, int iexit, float size = 50f, float dark = .5f, bool inverted = false)
        {
            IsoTriangle <PixelTriData> tri = new IsoTriangle <PixelTriData>
            {
                _base    = offset + Vector2f.AxisX * size / 2f,
                dims     = new Vector2f(size, size * TriUtil.RootThree / 2f),
                inverted = inverted
            };

            tri.Add(new PixelTriData(new PixelV {
                pos   = tri.Centroid,
                color = new Color(dark, dark, dark, 1f)
            }));


            var triCross = new TriCrosshatch <PixelTriData>(this, tri);

            triCross.DrawTriSpiral(pdPath, ientry, iexit);
        }
コード例 #10
0
        private PenDrawingPath arrowToNextDBUG(int i, PathData pdata, Matrix2f rot)
        {
            var      pp   = new PenDrawingPath();
            Vector2f last = Vector2f.Zero;

            foreach (var v in pdata.arrowFromThisToNext(i))
            {
                last = (rot * v) * viewBoxToPaperScale;
                pp.Add(new PenMove()
                {
                    destination = last
                });
            }
            pp.Add(new PenMove()
            {
                destination = last, up = true
            });
            return(pp);
        }
コード例 #11
0
            void TraceTri(PenDrawingPath pdPath, float imageToPaperScale, float toolDiam)
            {
                Vector2f closest, a, b;

                tri.ClosestPoint(entryPoint, out closest, out a, out b);

                if ((a - exitPoint).LengthSquared < (b - exitPoint).LengthSquared)
                {
                    Vector2f temp = a;
                    a = b;
                    b = temp;
                }

                closest *= imageToPaperScale; a *= imageToPaperScale; b *= imageToPaperScale;

                pdPath.addDrawMove(closest, adjacentExitPoint ? Color.blue : Color.yellow);
                pdPath.addDrawMove(a, ColorUtil.powderBlue);
                pdPath.addDrawMove(b, adjacentExitPoint ? ColorUtil.aqua : ColorUtil.pink);
            }
コード例 #12
0
        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);
        }
コード例 #13
0
        private PenDrawingPath dotAtDBUG(Vector2f v, Matrix2f rot, Color c, float size = 5f)
        {
            var pp = new PenDrawingPath();

            v = rot * v;
            Box2f box = new Box2f()
            {
                min = v, max = v + Vector2f.One * size
            };

            foreach (Vector2f l in box.getHorizontalLines())
            {
                pp.Add(new PenMove()
                {
                    destination = l * viewBoxToPaperScale, color = c
                });
            }
            pp.Add(new PenMove()
            {
                destination = v * viewBoxToPaperScale, up = true
            });
            return(pp);
        }
コード例 #14
0
            internal void DrawTriSpiral(PenDrawingPath pdPath, int ientry, int iexit)
            {
                int origExit = iexit;

                if (ientry == iexit)
                {
                    iexit = (ientry + 1) % 3;
                }
                int iother = (ientry + 1) % 3;

                if (iother == iexit)
                {
                    iother = (ientry + 2) % 3;
                }

                var border = tri.Border();
                var lookup = new int[] { ientry, iother, iexit };

                bool ccw;
                {
                    Vector3 a = (border[iother] - border[ientry]).ToVector3(0f);
                    Vector3 b = (border[iexit] - border[ientry]).ToVector3(0f);
                    ccw = Vector3.Cross(a, b).z > 0f;
                }

                var centroid = tri.Centroid;
                var radii    = new Vector2f[3];

                for (int i = 0; i < 3; ++i)
                {
                    radii[lookup[i]] = border[lookup[i]] - centroid;
                }

                float maxLoops = generator.generatorConfig.SkewMaxLoops * tri.InnerRadius / ((float)generator.machineConfig.toolDiameterMM / generator.viewBoxToPaperScale);

                maxLoops *= .5f;
                float loopsF = maxLoops * (float)(1d - (generator.generatorConfig.SkewTriPixelMean.Evaluate((float)tri.onlineNormalEstimator.mean())));
                int   loops  = Mathf.CeilToInt(loopsF);

                float incr      = 1f / loopsF;
                float halfIncr  = incr / 2f;
                float thirdIncr = incr / 3f;
                float sixthIncr = incr / 6f;

                float    rad;
                Vector2f move;

                pdPath.addDrawMove(border[ientry] * generator.viewBoxToPaperScale, Color.magenta);

                rad = 1f - halfIncr;
                for (int i = loops - 1; i >= 0; --i)
                {
                    for (int jj = 0; jj < 3; ++jj)
                    {
                        if (rad > 0f)
                        {
                            int j = ccw ? (2 - jj) : jj;
                            move = centroid + radii[lookup[j]] * rad;
                            pdPath.addDrawMove(move * generator.viewBoxToPaperScale, jj == 2 ? Color.cyan : Color.blue);
                        }
                        rad -= thirdIncr;
                    }
                }


                rad += thirdIncr + halfIncr;
                for (int i = 1; i <= loops; ++i)
                {
                    for (int jj = 2; jj >= 0; --jj)
                    {
                        if (rad > 0f)
                        {
                            int j = ccw ? (2 - jj) : jj;
                            move = centroid + radii[lookup[j]] * rad;
                            pdPath.addDrawMove(move * generator.viewBoxToPaperScale, jj == 0 ? ColorUtil.pink : ColorUtil.fuschia);
                        }
                        rad += thirdIncr;
                    }
                }


                pdPath.addDrawMove(border[origExit] * generator.viewBoxToPaperScale, ColorUtil.aqua);
            }
コード例 #15
0
        IEnumerable <PenDrawingPath> crosshatches(StripedPath stripedPath)
        {
            Matrix2f inverseRotation;
            PathData pdata;

            for (var stripeField = stripedPath.stripeField; stripeField != null; stripeField = stripeField.next)
            {
                inverseRotation = stripeField.rotation.Inverse();
                if (dbugSettings.dontRotateBackFinalPenPaths)
                {
                    inverseRotation = Matrix2f.Identity;
                }
                pdata = new PathData(SvgParser.SvgPath.RotatedClone(stripedPath.path, stripeField.rotation), _svgFileData.isYAxisInverted);

                int lastEnterEdgeIndex = -100;
                foreach (int i in pdata.enterFromLeftEdgeIndices)
                {
                    Vector2f edgeLower = pdata.areEnterLeftEdgesPosDelta ? pdata[i] : pdata.nextPoint(i);
                    Vector2f edgeUpper = pdata.areEnterLeftEdgesPosDelta ? pdata.nextPoint(i) : pdata[i];
                    Assert.IsTrue(edgeLower.y < edgeUpper.y, "something wrong at index: " + i);

                    Edge2f   leftEdge = new Edge2f(edgeLower, edgeUpper);
                    Vector2f leftIntersection;

                    // foreach y: find exit edges that span the y, find closest intersecion point
                    float y = stripeField.nextStripeYPosAbove(edgeLower.y);
                    for (; y < stripeField.nextStripeYPosAbove(edgeUpper.y); y += stripeField.interval)
                    {
                        if (!leftEdge.intersectionPointWithY(y, out leftIntersection))
                        {
                            continue;
                            //break; // want?
                        }


                        float closestXDelta = float.MaxValue;

                        for (int j = 0; j < pdata.exitFromLeftEdgeIndices.Count; ++j)
                        {
                            int    jV    = pdata.exitFromLeftEdgeIndices[j];
                            Edge2f jEdge = pdata.edgeAt(jV);

                            Vector2f intrsection;
                            if (jEdge.intersectionPointWithY(y, out intrsection))
                            {
                                float dif = intrsection.x - leftIntersection.x;
                                if (dif > 0f && dif < closestXDelta)
                                {
                                    closestXDelta = dif;
                                }
                            }
                        }

                        if (closestXDelta < float.MaxValue)
                        {
                            PenDrawingPath penPath = new PenDrawingPath();

                            penPath.addDownUpDrawMove(
                                (inverseRotation * leftIntersection) * viewBoxToPaperScale,
                                (inverseRotation * new Vector2f(leftIntersection.x + closestXDelta, y)) * viewBoxToPaperScale,
                                Color.black);
                            yield return(penPath);
                        }
                    }

                    lastEnterEdgeIndex = i;
                }
            }
        }
コード例 #16
0
        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;
                }
            }
        }
コード例 #17
0
ファイル: SCPen.cs プロジェクト: melsov/SVGCrosshatch
 public PenUpdate(PenDrawingPath path)
 {
     drawPath = path;
 }                                                          // PenMove from, PenMove to) { this.from = from; this.to = to; }