Ejemplo n.º 1
0
        private static void test_meshGen1()
        {
            Console.WriteLine("test_meshGen1");
            TriangulatedPolygonGenerator tg = new TriangulatedPolygonGenerator();

            tg.Polygon = new GeneralPolygon2d(new Polygon2d(
                                                  new List <Vector2d>()
            {
                // clockwise
                new Vector2d(0, 0),
                new Vector2d(0, 4),
                new Vector2d(5, 4),
                new Vector2d(5, 0)
            }
                                                  ));
            tg.Polygon.AddHole(new Polygon2d(
                                   new List <Vector2d>()
            {
                // counter-clockwise
                new Vector2d(1, 1),
                new Vector2d(2, 1),
                new Vector2d(1, 2)
            }
                                   ));
            tg.Generate();
            var m = tg.MakeDMesh();

            Console.WriteLine(TestUtil.WriteTestOutputMesh(m));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// available after call to UpdateSection()
        /// </summary>
        public DMesh3 GetSectionMesh(double simplifyTol = 0.01)
        {
            DMesh3 mesh = new DMesh3();

            if (localCurves.Loops == null)
            {
                return(mesh);
            }

            List <GeneralPolygon2d> solids = GetSolids();

            foreach (GeneralPolygon2d poly in solids)
            {
                poly.Simplify(simplifyTol, simplifyTol / 10, true);
                TriangulatedPolygonGenerator gen = new TriangulatedPolygonGenerator()
                {
                    Polygon = poly
                };
                DMesh3 polyMesh = gen.Generate().MakeDMesh();
                MeshTransforms.PerVertexTransform(polyMesh, (uv) => {
                    return(frameL.FromPlaneUV((Vector2f)uv.xy, 2));
                });
                MeshEditor.Append(mesh, polyMesh);
            }

            if (OutputSpace != CoordSpace.ObjectCoords)
            {
                MeshTransforms.PerVertexTransform(mesh, (v) => {
                    return(SceneTransforms.TransformTo((Vector3f)v, SO, CoordSpace.ObjectCoords, OutputSpace));
                });
            }

            return(mesh);
        }
Ejemplo n.º 3
0
        public static List <Polygon2d> Compute(GeneralPolygon2d poly, double minArea)
        {
            TriangulatedPolygonGenerator generator = new TriangulatedPolygonGenerator()
            {
                Polygon      = poly,
                Subdivisions = 16
            };
            DMesh3 mesh = generator.Generate().MakeDMesh();

            return(decompose_cluster_up(mesh, minArea));
        }
Ejemplo n.º 4
0
        private static void test_meshGen3()
        {
            Console.WriteLine("test_meshGen3");
            TriangulatedPolygonGenerator tg = new TriangulatedPolygonGenerator();
            var poly = new Polygon2d(
                new List <Vector2d>()
            {
                // clockwise
                new Vector2d(0, 0),
                new Vector2d(0, 9),
                new Vector2d(9, 9),
                new Vector2d(7, 7),
                new Vector2d(6.99999, 7),
                new Vector2d(2, 7),
                new Vector2d(2, 2.00001),
                new Vector2d(2, 2)
            });

            tg.Polygon = new GeneralPolygon2d(poly);
            tg.Generate();
            var mesh = tg.MakeDMesh();

            Console.WriteLine(TestUtil.WriteTestOutputMesh(mesh));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// test added to demonstrate https://github.com/gradientspace/geometry3Sharp/issues/114
        /// </summary>
        public static void test_TriangulatedPolygonGenerator_114()
        {
            Console.WriteLine("Testing TriangulatedPolygonGenerator");
            TriangulatedPolygonGenerator tg = new TriangulatedPolygonGenerator();

            tg.Polygon = new GeneralPolygon2d(new Polygon2d(
                                                  new List <Vector2d>()
            {
                new Vector2d(0, 0),
                new Vector2d(0, 4),
                new Vector2d(5, 4),
                new Vector2d(5, 0)
            }
                                                  ));
            tg.Polygon.AddHole(new Polygon2d(
                                   new List <Vector2d>()
            {
                new Vector2d(1, 1),
                new Vector2d(2, 1),
                new Vector2d(1, 2)
            }
                                   ));
            WriteGeneratedMesh(tg, "TriangulatedPolygonGenerator.obj");
        }
Ejemplo n.º 6
0
        virtual public void PreRender()
        {
            if (in_shutdown())
            {
                return;
            }

            if (parameters_dirty)
            {
                // offset
                List <GeneralPolygon2d> offset = ClipperUtil.RoundOffset(combined_all, offset_distance);
                // aggressively simplify after round offset...
                foreach (var poly in offset)
                {
                    poly.Simplify(path_width);
                }

                // subtract initial and add tiny gap so these don't get merged by slicer
                if (SubtractSolids)
                {
                    offset = ClipperUtil.Difference(offset, combined_solid);
                    offset = ClipperUtil.MiterOffset(offset, -path_width * 0.1);
                }

                offset = CurveUtils2.FilterDegenerate(offset, 0.001);
                foreach (var poly in offset)
                {
                    poly.Simplify(path_width * 0.02);
                }

                DMesh3     mesh   = new DMesh3();
                MeshEditor editor = new MeshEditor(mesh);
                foreach (var poly in offset)
                {
                    TriangulatedPolygonGenerator polygen = new TriangulatedPolygonGenerator()
                    {
                        Polygon = poly
                    };
                    editor.AppendMesh(polygen.Generate().MakeDMesh());
                }
                MeshTransforms.ConvertZUpToYUp(mesh);

                if (mesh.TriangleCount > 0)
                {
                    MeshExtrudeMesh extrude = new MeshExtrudeMesh(mesh);
                    extrude.ExtrudedPositionF = (v, n, vid) => {
                        return(v + Layers * layer_height * Vector3d.AxisY);
                    };
                    extrude.Extrude();
                    MeshTransforms.Translate(mesh, -mesh.CachedBounds.Min.y * Vector3d.AxisY);
                }

                PreviewSO.ReplaceMesh(mesh, true);

                //Vector3d translate = scene_bounds.Point(1, -1, 1);
                //translate.x += spiral.Bounds.Width + PathWidth;
                //Frame3f sceneF = Frame3f.Identity.Translated((Vector3f)translate);
                //PreviewSO.SetLocalFrame(sceneF, CoordSpace.SceneCoords);

                parameters_dirty = false;
            }
        }
Ejemplo n.º 7
0
        protected virtual void fill_bridge_region_decompose(GeneralPolygon2d poly, IFillPathScheduler2d scheduler, PrintLayerData layer_data)
        {
            poly.Simplify(0.1, 0.01, true);
            TriangulatedPolygonGenerator generator = new TriangulatedPolygonGenerator()
            {
                Polygon = poly, Subdivisions = 16
            };
            DMesh3 mesh = generator.Generate().MakeDMesh();
            //Util.WriteDebugMesh(mesh, "/Users/rms/scratch/bridgemesh.obj");


            //List<Polygon2d> polys = decompose_mesh_recursive(mesh);
            List <Polygon2d> polys = decompose_cluster_up(mesh);

            Util.WriteDebugMesh(mesh, "/Users/rms/scratch/bridgemesh_reduce.obj");

            double spacing = Settings.BridgeFillPathSpacingMM();

            foreach (Polygon2d polypart in polys)
            {
                Box2d    box   = polypart.MinimalBoundingBox(0.00001);
                Vector2d axis  = (box.Extent.x > box.Extent.y) ? box.AxisY : box.AxisX;
                double   angle = Math.Atan2(axis.y, axis.x) * MathUtil.Rad2Deg;

                GeneralPolygon2d gp = new GeneralPolygon2d(polypart);

                ShellsFillPolygon shells_fill = new ShellsFillPolygon(gp);
                shells_fill.PathSpacing            = Settings.SolidFillPathSpacingMM();
                shells_fill.ToolWidth              = Settings.Machine.NozzleDiamMM;
                shells_fill.Layers                 = 1;
                shells_fill.InsetFromInputPolygonX = 0.25;
                shells_fill.ShellType              = ShellsFillPolygon.ShellTypes.BridgeShell;
                shells_fill.FilterSelfOverlaps     = false;
                shells_fill.Compute();
                scheduler.AppendCurveSets(shells_fill.GetFillCurves());
                var fillPolys = shells_fill.InnerPolygons;

                double offset = Settings.Machine.NozzleDiamMM * Settings.SolidFillBorderOverlapX;
                fillPolys = ClipperUtil.MiterOffset(fillPolys, offset);

                foreach (var fp in fillPolys)
                {
                    BridgeLinesFillPolygon fill_gen = new BridgeLinesFillPolygon(fp)
                    {
                        InsetFromInputPolygon = false,
                        PathSpacing           = spacing,
                        ToolWidth             = Settings.Machine.NozzleDiamMM,
                        AngleDeg = angle,
                    };
                    fill_gen.Compute();
                    scheduler.AppendCurveSets(fill_gen.GetFillCurves());
                }
            }

            // fit bbox to try to find fill angle that has shortest spans
            //Box2d box = poly.Outer.MinimalBoundingBox(0.00001);
            //Vector2d axis = (box.Extent.x > box.Extent.y) ? box.AxisY : box.AxisX;
            //double angle = Math.Atan2(axis.y, axis.x) * MathUtil.Rad2Deg;

            // [RMS] should we do something like this?
            //if (Settings.SolidFillBorderOverlapX > 0) {
            //	double offset = Settings.Machine.NozzleDiamMM * Settings.SolidFillBorderOverlapX;
            //	fillPolys = ClipperUtil.MiterOffset(fillPolys, offset);
            //}
        }
        public IntermediateMeshGenerator Generate()
        {
            var plateSegmentGenerator = Context.Plate2d;

            var cornerPoints = Context
                               .SegmentIndexes
                               .Select(idx => plateSegmentGenerator.InnerBendCorner.rotate2d(Context.Config.SegmentAngle(idx)))
                               .ToList();

            if (Context.Config.spindelRadius == 0)
            {
                for (var idx = 0; idx < cornerPoints.Count; idx++)
                {
                    var nextIdx = (idx + 1) % cornerPoints.Count;

                    Intermediate.counterClockwiseSingleSidedFromFront(
                        Vector2d.Zero.to3d(Context.halfPlateHeight),
                        cornerPoints[idx].to3d(Context.halfPlateHeight),
                        cornerPoints[nextIdx].to3d(Context.halfPlateHeight)
                        );

                    Intermediate.counterClockwiseSingleSidedFromFront(
                        Vector2d.Zero.to3d(-Context.halfPlateHeight),
                        cornerPoints[nextIdx].to3d(-Context.halfPlateHeight),
                        cornerPoints[idx].to3d(-Context.halfPlateHeight)
                        );
                }

                return(Intermediate);
            }

            List <Vector2d> spindelPoints = new List <Vector2d>();

            if (Context.Config.spindelCut == 0)
            {
                spindelPoints = Generators.counterClockwiseCirclePoints(
                    Context.Config.spindelPoints,
                    Vector2d.Zero,
                    Context.Config.spindelRadius
                    );

                /*
                 * Intermediate.Extrude(spindelPoints, Context.Config.plateHeight, true);
                 *
                 * var nearestDistanceIndexes = cornerPoints.Select(point =>
                 * {
                 *  var distances = spindelPoints.Select(p => p.Distance(point)).ToList();
                 *  var nearestPointIndex = distances.FindIndex(d => d == distances.Min());
                 *  return nearestPointIndex;
                 * }).ToList();
                 *
                 * for (var idx = 0; idx < cornerPoints.Count; idx++)
                 * {
                 *  var nearestPointIndex = nearestDistanceIndexes[idx];
                 *
                 *  var nextIdx = (idx + 1) % cornerPoints.Count;
                 *  var nextNearestPointIndex = nearestDistanceIndexes[nextIdx];
                 *
                 *  var polygonPoints = new List<Vector2d>();
                 *  polygonPoints.AddRange(
                 *      new []
                 *      {
                 *          cornerPoints[idx],
                 *          cornerPoints[nextIdx]
                 *      });
                 *
                 *  var spindelPart = new List<Vector2d>();
                 *  var pointsToTake = nextNearestPointIndex < nearestPointIndex
                 *      ? nextNearestPointIndex + spindelPoints.Count - nearestPointIndex + 1
                 *      : nextNearestPointIndex - nearestPointIndex + 1;
                 *
                 *  spindelPart = Enumerable.Range(nearestPointIndex, pointsToTake)
                 *      .Select(i => spindelPoints[i % spindelPoints.Count])
                 *      .Reverse()
                 *      .ToList();
                 *
                 *  polygonPoints.AddRange(spindelPart);
                 *
                 *  var polygonizer = new TriangulatedPolygonGenerator()
                 *  {
                 *      Polygon = new GeneralPolygon2d( new Polygon2d(polygonPoints) )
                 *  };
                 *  polygonizer.Generate();
                 *
                 *  var polygonMesh = new IntermediateMeshGenerator();
                 *  polygonMesh.Append(polygonizer);
                 *
                 *  Intermediate.Append(new IntermediateMeshGenerator().Append(polygonMesh).Offset(new Vector3d(0, 0, Context.halfPlateHeight)));
                 *  Intermediate.Append(new IntermediateMeshGenerator().Append(polygonMesh).Offset(new Vector3d(0, 0, -Context.halfPlateHeight)).ReverseTriagles());
                 * }
                 */
            }
            else
            {
                var spindelCutX = Context.Config.spindelRadius - Context.Config.spindelCut;
                var cutItx      = Intersector.CircelLineIntersection(
                    Vector2d.Zero,
                    Context.Config.spindelRadius,
                    new Vector2d(spindelCutX, 0),
                    new Vector2d(spindelCutX, 1)
                    );

                spindelPoints = Generators.counterClockwiseCircleSegments(
                    Context.Config.spindelPoints,
                    Vector2d.Zero,
                    cutItx.Single(p => p.y > 0),
                    cutItx.Single(p => p.y < 0)
                    );

                //Intermediate.Extrude(spindelSegments, Context.Config.plateHeight, true);
            }


            Intermediate.Extrude(spindelPoints, Context.Config.plateHeight, true);

            var nearestDistanceIndexes = cornerPoints.Select(point =>
            {
                var distances         = spindelPoints.Select(p => p.Distance(point)).ToList();
                var nearestPointIndex = distances.FindIndex(d => d == distances.Min());
                return(nearestPointIndex);
            }).ToList();

            for (var idx = 0; idx < cornerPoints.Count; idx++)
            {
                var nearestPointIndex = nearestDistanceIndexes[idx];

                var nextIdx = (idx + 1) % cornerPoints.Count;
                var nextNearestPointIndex = nearestDistanceIndexes[nextIdx];

                var polygonPoints = new List <Vector2d>();
                polygonPoints.AddRange(
                    new[]
                {
                    cornerPoints[idx],
                    cornerPoints[nextIdx]
                });

                var spindelPart  = new List <Vector2d>();
                var pointsToTake = nextNearestPointIndex < nearestPointIndex
                    ? nextNearestPointIndex + spindelPoints.Count - nearestPointIndex + 1
                    : nextNearestPointIndex - nearestPointIndex + 1;

                spindelPart = Enumerable.Range(nearestPointIndex, pointsToTake)
                              .Select(i => spindelPoints[i % spindelPoints.Count])
                              .Reverse()
                              .ToList();

                polygonPoints.AddRange(spindelPart);

                var polygonizer = new TriangulatedPolygonGenerator()
                {
                    Polygon = new GeneralPolygon2d(new Polygon2d(polygonPoints))
                };
                polygonizer.Generate();

                var polygonMesh = new IntermediateMeshGenerator();
                polygonMesh.Append(polygonizer);

                Intermediate.Append(new IntermediateMeshGenerator().Append(polygonMesh).Offset(new Vector3d(0, 0, Context.halfPlateHeight)));
                Intermediate.Append(new IntermediateMeshGenerator().Append(polygonMesh).Offset(new Vector3d(0, 0, -Context.halfPlateHeight)).ReverseTriagles());
            }

            return(Intermediate);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Generates the actual mesh for the polyhedron
        /// </summary>
        private void MakeMesh()
        {
            MeshFilter mf;

            mf = Shape.GetComponent <MeshFilter>();
            if (mf == null)
            {
                mf = Shape.AddComponent <MeshFilter>();
            }
            mf.mesh = null;
            Mesh mesh = new Mesh();
            TriangulatedPolygonGenerator tpg = new TriangulatedPolygonGenerator();
            Frame3f frame = new Frame3f();

            tpg.Polygon = Polygon.ToPolygon(ref frame);
            tpg.Generate();
            int nv = tpg.vertices.Count;

            VertexTable.Clear();

            foreach (Dataline ring in Polygon)
            {
                foreach (VertexLookup v in ring.VertexTable)
                {
                    VertexTable.Add(v);
                }
            }
            IEnumerable <Vector3d> vlist = tpg.vertices.AsVector3d();

            Vector3[] vertices = new Vector3[vlist.Count()];

            for (int i = 0; i < vlist.Count(); i++)
            {
                Vector3d v = vlist.ElementAt(i);
                try {
                    VertexLookup vl = VertexTable.Find(item => v.xy.Distance(frame.ToPlaneUV(item.Com.transform.position, 3)) < 0.001);
                    vertices[i] = Shape.transform.InverseTransformPoint(vl.Com.transform.position);
                    vl.pVertex  = i;
                } catch {
                    VertexTable.Add(new VertexLookup()
                    {
                        pVertex = i, Com = VertexTable[0].Com
                    });
                    vertices[i] = Shape.transform.InverseTransformPoint((Vector3)frame.FromFrameV(v));
                }
            }

            List <Vector2>         uvs  = new List <Vector2>();
            IEnumerable <Vector2d> uv2d = tpg.uv.AsVector2f();

            foreach (Vector2d uv in uv2d)
            {
                uvs.Add((Vector2)uv);
            }
            mesh.vertices  = vertices.ToArray();
            mesh.triangles = tpg.triangles.ToArray <int>();
            mesh.uv        = uvs.ToArray <Vector2>();

            mesh.RecalculateBounds();
            mesh.RecalculateNormals();

            mf.mesh = mesh;
        }