Пример #1
0
        static GCodeInfo GenerateGCodeForFile(string filename, Action <string, string> errorF, Func <bool> cancelF)
        {
            GCodeInfo info = new GCodeInfo();

            DMesh3 mesh = StandardMeshReader.ReadMesh(filename);

            if (mesh == null || mesh.TriangleCount == 0)
            {
                throw new Exception("File " + filename + " is invalid or empty");
            }

            bool ENABLE_SUPPORT_ZSHIFT = true;

            // configure settings
            MakerbotSettings settings = new MakerbotSettings(Makerbot.Models.Replicator2);

            //MonopriceSettings settings = new MonopriceSettings(Monoprice.Models.MP_Select_Mini_V2);
            //PrintrbotSettings settings = new PrintrbotSettings(Printrbot.Models.Plus);
            settings.ExtruderTempC             = 200;
            settings.Shells                    = 2;
            settings.InteriorSolidRegionShells = 0;
            settings.SparseLinearInfillStepX   = 10;
            settings.ClipSelfOverlaps          = false;

            settings.GenerateSupport    = true;
            settings.EnableSupportShell = true;

            PrintMeshAssembly meshes = new PrintMeshAssembly();

            meshes.AddMesh(mesh);

            // slice meshes
            MeshPlanarSlicerPro slicer = new MeshPlanarSlicerPro()
            {
                LayerHeightMM = settings.LayerHeightMM,
                SliceFactoryF = PlanarSlicePro.FactoryF
            };

            slicer.Add(meshes);
            slicer.CancelF = cancelF;
            PlanarSliceStack slices = slicer.Compute();

            if (slicer.WasCancelled)
            {
                return(info);
            }
            info.SliceCount  = slices.Count;
            info.SliceBounds = slices.Bounds;

            // run print generator
            SingleMaterialFFFPrintGenPro printGen =
                new SingleMaterialFFFPrintGenPro(meshes, slices, settings);

            printGen.ErrorF  = errorF;
            printGen.CancelF = cancelF;

            if (ENABLE_SUPPORT_ZSHIFT)
            {
                printGen.LayerPostProcessor = new SupportConnectionPostProcessor()
                {
                    ZOffsetMM = 0.2f
                }
            }
            ;
            printGen.AccumulatePathSet = true;

            printGen.Generate();
            if (printGen.WasCancelled)
            {
                return(info);
            }

            GCodeFile genGCode = printGen.Result;

            info.PathBounds    = printGen.AccumulatedPaths.Bounds;
            info.ExtrudeBounds = printGen.AccumulatedPaths.ExtrudeBounds;
            info.TotalLength   = CurveUtils.ArcLength(printGen.AccumulatedPaths.AllPositionsItr());
            info.GCodeLines    = genGCode.LineCount;

            // write to in-memory string
            StandardGCodeWriter writer = new StandardGCodeWriter();

            using (MemoryStream membuf = new MemoryStream()) {
                using (StreamWriter w = new StreamWriter(membuf)) {
                    writer.WriteFile(genGCode, w);
                    info.GCodeBytes = (int)membuf.Length;
                }
            }

            info.completed = true;

            return(info);
        }
    }
Пример #2
0
        public override void Generate()
        {
            double tCurveLen            = CurveUtils.ArcLength(Curve);
            SampledArcLengthParam pAxis = new SampledArcLengthParam(Axis, Axis.Length);
            double tAxisLen             = pAxis.ArcLength;
            double tScale = tAxisLen / tCurveLen;

            int nRings       = Curve.Length;
            int nRingSize    = (NoSharedVertices) ? Slices + 1 : Slices;
            int nCapVertices = (NoSharedVertices) ? Slices + 1 : 1;

            if (Capped == false)
            {
                nCapVertices = 0;
            }

            vertices = new VectorArray3d(nRingSize * nRings + 2 * nCapVertices);
            uv       = new VectorArray2f(vertices.Count);
            normals  = new VectorArray3f(vertices.Count);

            int nSpanTris = (nRings - 1) * (2 * Slices);
            int nCapTris  = (Capped) ? 2 * Slices : 0;

            triangles = new IndexArray3i(nSpanTris + nCapTris);

            float fDelta = (float)((Math.PI * 2.0) / Slices);

            double      tCur = 0;
            CurveSample s    = pAxis.Sample(tCur);
            Frame3f     f0   = new Frame3f((Vector3F)s.position, (Vector3F)s.tangent, 1);
            Frame3f     fCur = f0;

            // generate tube
            for (int ri = 0; ri < nRings; ++ri)
            {
                if (ri > 0)
                {
                    tCur       += (Curve[ri] - Curve[ri - 1]).Length;
                    s           = pAxis.Sample(tCur * tScale);
                    fCur.Origin = (Vector3F)s.position;
                    fCur.AlignAxis(1, (Vector3F)s.tangent);
                }

                Vector3D v_along  = Curve[ri];
                Vector3F v_frame  = fCur.ToFrameP((Vector3F)v_along);
                float    uv_along = (float)ri / (float)(nRings - 1);

                // generate vertices
                int nStartR = ri * nRingSize;
                for (int j = 0; j < nRingSize; ++j)
                {
                    float angle = (float)j * fDelta;

                    // [TODO] this is not efficient...use Matrix3f?
                    Vector3F v_rot = Quaternionf.AxisAngleR(Vector3F.AxisY, angle) * v_frame;
                    Vector3D v_new = fCur.FromFrameP(v_rot);
                    int      k     = nStartR + j;
                    vertices[k] = v_new;

                    float uv_around = (float)j / (float)(nRingSize);
                    uv[k] = new Vector2F(uv_along, uv_around);

                    // [TODO] proper normal
                    Vector3F n = (Vector3F)(v_new - fCur.Origin).Normalized;
                    normals[k] = n;
                }
            }


            // generate triangles
            int ti = 0;

            for (int ri = 0; ri < nRings - 1; ++ri)
            {
                int r0 = ri * nRingSize;
                int r1 = r0 + nRingSize;
                for (int k = 0; k < nRingSize - 1; ++k)
                {
                    triangles.Set(ti++, r0 + k, r0 + k + 1, r1 + k + 1, Clockwise);
                    triangles.Set(ti++, r0 + k, r1 + k + 1, r1 + k, Clockwise);
                }
                if (NoSharedVertices == false)        // close disc if we went all the way
                {
                    triangles.Set(ti++, r1 - 1, r0, r1, Clockwise);
                    triangles.Set(ti++, r1 - 1, r1, r1 + nRingSize - 1, Clockwise);
                }
            }



            if (Capped)
            {
                // find avg start loop size
                Vector3D vAvgStart = Vector3D.Zero, vAvgEnd = Vector3D.Zero;
                for (int k = 0; k < Slices; ++k)
                {
                    vAvgStart += vertices[k];
                    vAvgEnd   += vertices[(nRings - 1) * nRingSize + k];
                }
                vAvgStart /= (double)Slices;
                vAvgEnd   /= (double)Slices;

                Frame3f fStart = f0;
                fStart.Origin = (Vector3F)vAvgStart;
                Frame3f fEnd = fCur;
                fEnd.Origin = (Vector3F)vAvgEnd;



                // add endcap verts
                int nBottomC = nRings * nRingSize;
                vertices[nBottomC]  = fStart.Origin;
                uv[nBottomC]        = new Vector2F(0.5f, 0.5f);
                normals[nBottomC]   = -fStart.Z;
                startCapCenterIndex = nBottomC;

                int nTopC = nBottomC + 1;
                vertices[nTopC]   = fEnd.Origin;
                uv[nTopC]         = new Vector2F(0.5f, 0.5f);
                normals[nTopC]    = fEnd.Z;
                endCapCenterIndex = nTopC;

                if (NoSharedVertices)
                {
                    // duplicate first loop and make a fan w/ bottom-center
                    int nExistingB = 0;
                    int nStartB    = nTopC + 1;
                    for (int k = 0; k < Slices; ++k)
                    {
                        vertices[nStartB + k] = vertices[nExistingB + k];
                        //uv[nStartB + k] = (Vector2f)Polygon.Vertices[k].Normalized;

                        float  angle = (float)k * fDelta;
                        double cosa = Math.Cos(angle), sina = Math.Sin(angle);
                        uv[nStartB + k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina));

                        normals[nStartB + k] = normals[nBottomC];
                    }
                    append_disc(Slices, nBottomC, nStartB, true, Clockwise, ref ti);

                    // duplicate second loop and make fan
                    int nExistingT = nRingSize * (nRings - 1);
                    int nStartT    = nStartB + Slices;
                    for (int k = 0; k < Slices; ++k)
                    {
                        vertices[nStartT + k] = vertices[nExistingT + k];
                        //uv[nStartT + k] = (Vector2f)Polygon.Vertices[k].Normalized;

                        float  angle = (float)k * fDelta;
                        double cosa = Math.Cos(angle), sina = Math.Sin(angle);
                        uv[nStartT + k] = new Vector2F(0.5f * (1.0f + cosa), 0.5f * (1 + sina));


                        normals[nStartT + k] = normals[nTopC];
                    }
                    append_disc(Slices, nTopC, nStartT, true, !Clockwise, ref ti);
                }
                else
                {
                    append_disc(Slices, nBottomC, 0, true, Clockwise, ref ti);
                    append_disc(Slices, nTopC, nRingSize * (nRings - 1), true, !Clockwise, ref ti);
                }
            }
        }
Пример #3
0
        static void Main(string[] args)
        {
            GCodeInfo info = new GCodeInfo();

            string filename = args[0];

            DMesh3           mesh   = StandardMeshReader.ReadMesh(filename);
            AxisAlignedBox3d bounds = mesh.CachedBounds;

            MeshTransforms.Scale(mesh, MAX_DIM_MM / bounds.MaxDim);
            Vector3d basePt = mesh.CachedBounds.Point(0, 0, -1);

            MeshTransforms.Translate(mesh, -basePt);

            if (mesh.TriangleCount > MAX_TRI_COUNT)
            {
                Reducer r = new Reducer(mesh);
                r.ReduceToTriangleCount(MAX_TRI_COUNT);
                mesh = new DMesh3(mesh, true);
            }

            var start = DateTime.Now;

            bool ENABLE_SUPPORT_ZSHIFT = true;

            try {
                // configure settings
                MakerbotSettings settings = new MakerbotSettings(Makerbot.Models.Replicator2);
                //MonopriceSettings settings = new MonopriceSettings(Monoprice.Models.MP_Select_Mini_V2);
                //PrintrbotSettings settings = new PrintrbotSettings(Printrbot.Models.Plus);
                settings.ExtruderTempC             = 200;
                settings.Shells                    = 2;
                settings.InteriorSolidRegionShells = 0;
                settings.SparseLinearInfillStepX   = 10;
                settings.ClipSelfOverlaps          = false;

                settings.GenerateSupport    = true;
                settings.EnableSupportShell = true;

                PrintMeshAssembly meshes = new PrintMeshAssembly();
                meshes.AddMesh(mesh);

                // slice meshes
                MeshPlanarSlicerPro slicer = new MeshPlanarSlicerPro()
                {
                    LayerHeightMM = settings.LayerHeightMM,
                    SliceFactoryF = PlanarSlicePro.FactoryF
                };
                slicer.Add(meshes);
                PlanarSliceStack slices = slicer.Compute();
                info.SliceCount  = slices.Count;
                info.SliceBounds = slices.Bounds;

                // run print generator
                SingleMaterialFFFPrintGenPro printGen =
                    new SingleMaterialFFFPrintGenPro(meshes, slices, settings);

                if (ENABLE_SUPPORT_ZSHIFT)
                {
                    printGen.LayerPostProcessor = new SupportConnectionPostProcessor()
                    {
                        ZOffsetMM = 0.2f
                    }
                }
                ;
                printGen.AccumulatePathSet = true;

                printGen.Generate();

                GCodeFile genGCode = printGen.Result;

                info.PathBounds    = printGen.AccumulatedPaths.Bounds;
                info.ExtrudeBounds = printGen.AccumulatedPaths.ExtrudeBounds;
                info.TotalLength   = CurveUtils.ArcLength(printGen.AccumulatedPaths.AllPositionsItr());
                info.GCodeLines    = genGCode.LineCount;

                // write to in-memory string
                StandardGCodeWriter writer = new StandardGCodeWriter();
                using (MemoryStream membuf = new MemoryStream()) {
                    using (StreamWriter w = new StreamWriter(membuf)) {
                        writer.WriteFile(genGCode, w);
                        info.GCodeBytes = (int)membuf.Length;
                    }
                }

                // try to force destructor error
                printGen = null;
                genGCode = null;
                GC.Collect();
            } catch (Exception e) {
                System.Console.WriteLine("EXCEPTION:" + e.Message);
                return;
            }

            var end     = DateTime.Now;
            int seconds = (int)(end - start).TotalSeconds;

            System.Console.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7},",
                                     filename, mesh.TriangleCount, "OK", seconds, info.SliceCount, info.GCodeLines, info.GCodeBytes, (int)info.TotalLength);
        }
Пример #4
0
        public DMesh3 CreateMesh(List <Vector3d> path,
                                 List <Polygon2d> polys,
                                 VectorArray3d seam)
        {
            // Ignore first and last path/polys for mesh generation.
            // We just need the extra path positions to calculate a
            // continuous tangent at the seams.
            List <Vector3d> pathXZ = new List <Vector3d>();

            for (int i = 0; i < path.Count; i++)
            {
                pathXZ.Add(new Vector3d(path[i].x, 0, path[i].z));
            }

            int nVerts = path.Count - 2;
            int nPolys = polys.Count - 2;
            // Same VertexCount for all Polygons.
            int nSlices   = polys[0].VertexCount;
            int nPolySize = nSlices + 1;
            int nVecs     = nVerts * nPolySize;

            vertices = new VectorArray3d(nVecs);
            normals  = new VectorArray3f(nVecs);
            uv       = new VectorArray2f(nVecs);

            int quad_strips = nVerts - 1;
            int nSpanTris   = quad_strips * (2 * nSlices);

            triangles = new IndexArray3i(nSpanTris);

            Frame3f fCur         = new Frame3f(frame);
            double  pathLength   = CurveUtils.ArcLength(path.GetRange(1, nVerts));
            double  accum_path_u = 0;

            for (int ri = 0; ri < nPolys; ++ri)
            {
                int      si      = ri + 1; // actual path/polys index for mesh
                Vector3d tangent = CurveUtils.GetTangent(pathXZ, si);
                fCur.Origin = (Vector3f)path[si];
                fCur.AlignAxis(2, (Vector3f)tangent);

                int    nStartR      = ri * nPolySize;
                double accum_ring_v = 0;
                bool   copy         = ri == nPolys - 1;
                bool   paste        = ri == 0;

                for (int j = 0; j < nPolySize; ++j)
                {
                    int      k      = nStartR + j;
                    Vector2d pv     = polys[si].Vertices[j % nSlices];
                    Vector2d pvNext = polys[si].Vertices[(j + 1) % nSlices];
                    Vector3d v      = fCur.FromPlaneUV((Vector2f)pv, 2);
                    vertices[k] = v;
                    Vector3f n = (Vector3f)(v - fCur.Origin).Normalized;
                    normals[k]    = n;
                    uv[k]         = new Vector2f(accum_path_u, accum_ring_v);
                    accum_ring_v += (pv.Distance(pvNext) / polys[si].ArcLength);
                    if (copy)
                    {
                        Seam[j] = vertices[k];
                    }
                    else if (paste)
                    {
                        vertices[k] = seam[j];
                    }
                }
                double d = path[si].Distance(path[si + 1]);
                accum_path_u += d / pathLength;
            }

            int nStop = nVerts - 1;
            int ti    = 0;

            for (int ri = 0; ri < nStop; ++ri)
            {
                int r0 = ri * nPolySize;
                int r1 = r0 + nPolySize;
                for (int k = 0; k < nPolySize - 1; ++k)
                {
                    triangles.Set(ti++, r0 + k, r0 + k + 1, r1 + k + 1, Clockwise);
                    triangles.Set(ti++, r0 + k, r1 + k + 1, r1 + k, Clockwise);
                }
            }
            return(MakeDMesh());
        }