static void generate_stacked_polygon(SingleMaterialFFFCompiler compiler, SingleMaterialFFFSettings settings) { int NLayers = 10; for (int layer_i = 0; layer_i < NLayers; ++layer_i) { // create data structures for organizing this layer ToolpathSetBuilder layer_builder = new ToolpathSetBuilder(); SequentialScheduler2d scheduler = new SequentialScheduler2d(layer_builder, settings); if (layer_i == 0) { scheduler.SpeedHint = SchedulerSpeedHint.Careful; } // initialize layer layer_builder.Initialize(compiler.NozzlePosition); // layer-up layer_builder.AppendZChange(settings.LayerHeightMM, settings.ZTravelSpeed); // schedule a circle FillPolygon2d circle_poly = new FillPolygon2d(Polygon2d.MakeCircle(25.0f, 64)); circle_poly.TypeFlags = FillTypeFlags.OuterPerimeter; scheduler.AppendPolygon2d(circle_poly); // pass paths to compiler compiler.AppendPaths(layer_builder.Paths, settings); } }
static void generate_stacked_wavy_circle(SingleMaterialFFFCompiler compiler, SingleMaterialFFFSettings settings) { double height = 20.0; // mm int NLayers = (int)(height / settings.LayerHeightMM); // 20mm int NSteps = 128; double radius = 15.0; double frequency = 6; double scale = 5.0; for (int layer_i = 0; layer_i < NLayers; ++layer_i) { // create data structures for organizing this layer ToolpathSetBuilder layer_builder = new ToolpathSetBuilder(); SequentialScheduler2d scheduler = new SequentialScheduler2d(layer_builder, settings); if (layer_i == 0) { scheduler.SpeedHint = SchedulerSpeedHint.Careful; } // initialize and layer-up layer_builder.Initialize(compiler.NozzlePosition); layer_builder.AppendZChange(settings.LayerHeightMM, settings.ZTravelSpeed); // start with circle FillPolygon2d circle_poly = new FillPolygon2d(Polygon2d.MakeCircle(radius, NSteps)); // apply a wave deformation to circle, with wave height increasing with Z double layer_scale = MathUtil.Lerp(0, scale, (double)layer_i / (double)NLayers); for (int i = 0; i < NSteps; ++i) { Vector2d v = circle_poly[i]; double angle = Math.Atan2(v.y, v.x); double r = v.Length; r += layer_scale * Math.Sin(frequency * angle); circle_poly[i] = r * v.Normalized; } circle_poly.TypeFlags = FillTypeFlags.OuterPerimeter; scheduler.AppendPolygon2d(circle_poly); // pass paths to compiler compiler.AppendPaths(layer_builder.Paths, settings); } }
static GCodeFile generate_cnc_test(MeshPlanarMillSlicer.Result sliceSets, RepRapSettings settings, out ToolpathSet AccumulatedPaths) { int PLUNGE_SPEED = 800; AccumulatedPaths = new ToolpathSet(); GCodeFileAccumulator file_accumulator = new GCodeFileAccumulator(); GCodeBuilder builder = new GCodeBuilder(file_accumulator); BaseThreeAxisMillingCompiler Compiler = new BaseThreeAxisMillingCompiler(builder, settings, GenericMillingAssembler.Factory); Compiler.Begin(); /* * Clearing pass */ PlanarSliceStack clearingSlices = sliceSets.Clearing; int N = clearingSlices.Count; // assuming origin is at top of stock so we actaully are going down in Z layers for (int k = 0; k < N; ++k) { clearingSlices[k].Z = -(sliceSets.TopZ - clearingSlices[k].Z); } for (int layeri = 0; layeri < N; layeri++) { PlanarSlice slice = clearingSlices[layeri]; Compiler.AppendComment(string.Format("clearing layer {0} - {1}mm", layeri, slice.Z)); ToolpathSetBuilder layer_builder = new ToolpathSetBuilder() { MoveType = ToolpathTypes.Cut }; layer_builder.Initialize(Compiler.ToolPosition); // To do a layer-change, we need to plunge down at the first scheduled cutting position. // However we will not know that until we schedule the first set of paths. // So, we configure SequentialScheduler2d to call this function when it knows this information, // and then we can travel to the new XY position before we plunge to new Z Action <List <FillCurveSet2d>, SequentialScheduler2d> DoZChangeF = (curves, scheduler) => { Vector2d startPosXY = (curves[0].Loops.Count > 0) ? curves[0].Loops[0].Start : curves[0].Curves[0].Start; Vector3d startPosXYZ = new Vector3d(startPosXY.x, startPosXY.y, slice.Z); // TODO: we should retract at faster speed here? maybe use custom function that does this better? layer_builder.AppendTravel(startPosXYZ, PLUNGE_SPEED); scheduler.OnAppendCurveSetsF = null; }; SequentialScheduler2d layerScheduler = new SequentialScheduler2d(layer_builder, settings) { ExtrudeOnShortTravels = true, ShortTravelDistance = settings.Machine.NozzleDiamMM * 1.5 }; layerScheduler.OnAppendCurveSetsF = DoZChangeF; GroupScheduler2d groupScheduler = new GroupScheduler2d(layerScheduler, Compiler.ToolPosition.xy); foreach (GeneralPolygon2d shape in slice.Solids) { ShellsFillPolygon shells_gen = new ShellsFillPolygon(shape) { PathSpacing = settings.ShellsFillPathSpacingMM(), ToolWidth = settings.Machine.NozzleDiamMM, Layers = 10, OuterShellLast = false, DiscardTinyPerimterLengthMM = 1, DiscardTinyPolygonAreaMM2 = 1 }; shells_gen.Compute(); groupScheduler.BeginGroup(); groupScheduler.AppendCurveSets(shells_gen.Shells); groupScheduler.EndGroup(); } Compiler.AppendPaths(layer_builder.Paths, settings); AccumulatedPaths.Append(layer_builder.Paths); } /* * Horizontal finish pass */ PlanarSliceStack horzSlices = sliceSets.HorizontalFinish; int NH = horzSlices.Count; // assuming origin is at top of stock so we actaully are going down in Z layers for (int k = 0; k < NH; ++k) { horzSlices[k].Z = -(sliceSets.TopZ - horzSlices[k].Z); } for (int layeri = 0; layeri < NH; layeri++) { PlanarSlice slice = horzSlices[layeri]; Compiler.AppendComment(string.Format("horz finish layer {0} - {1}mm", layeri, slice.Z)); ToolpathSetBuilder layer_builder = new ToolpathSetBuilder() { MoveType = ToolpathTypes.Cut }; layer_builder.Initialize(Compiler.ToolPosition); Action <List <FillCurveSet2d>, SequentialScheduler2d> DoZChangeF = (curves, scheduler) => { Vector2d startPosXY = (curves[0].Loops.Count > 0) ? curves[0].Loops[0].Start : curves[0].Curves[0].Start; Vector3d startPosXYZ = new Vector3d(startPosXY.x, startPosXY.y, slice.Z); // TODO: we should retract at faster speed here? maybe use custom function that does this better? layer_builder.AppendTravel(startPosXYZ, PLUNGE_SPEED); scheduler.OnAppendCurveSetsF = null; }; SequentialScheduler2d layerScheduler = new SequentialScheduler2d(layer_builder, settings) { ExtrudeOnShortTravels = true, ShortTravelDistance = settings.Machine.NozzleDiamMM * 1.5 }; layerScheduler.OnAppendCurveSetsF = DoZChangeF; GroupScheduler2d groupScheduler = new GroupScheduler2d(layerScheduler, Compiler.ToolPosition.xy); foreach (GeneralPolygon2d shape in slice.Solids) { ShellsFillPolygon shells_gen = new ShellsFillPolygon(shape) { //InsetFromInputPolygonX = 0.0, PathSpacing = settings.ShellsFillPathSpacingMM(), ToolWidth = settings.Machine.NozzleDiamMM, Layers = 10, OuterShellLast = false, PreserveInputInsetTopology = false, DiscardTinyPerimterLengthMM = 1, DiscardTinyPolygonAreaMM2 = 1 }; shells_gen.Compute(); groupScheduler.BeginGroup(); groupScheduler.AppendCurveSets(shells_gen.Shells); groupScheduler.EndGroup(); } Compiler.AppendPaths(layer_builder.Paths, settings); AccumulatedPaths.Append(layer_builder.Paths); } // return to home position ToolpathSetBuilder finishBuilder = new ToolpathSetBuilder() { MoveType = ToolpathTypes.Cut }; finishBuilder.Initialize(Compiler.ToolPosition); finishBuilder.AppendTravel(Vector3d.Zero, PLUNGE_SPEED); Compiler.AppendPaths(finishBuilder.Paths, settings); Compiler.End(); return(file_accumulator.File); }