//Create a movement from a point public SilkwormMovement(Point3d point, Delimiter s_Delimiter) { blobPoint = point; sDelimiter = s_Delimiter; double eLengthAll = s_Delimiter.startPressure + s_Delimiter.endPressure; double fTimeAll = s_Delimiter.startSpeed + s_Delimiter.endSpeed; complete = true; isPt = true; Length = eLengthAll; Time = fTimeAll; ZDomain = new Interval(point.Z, point.Z); }
//DEFAULT CONSTRUCTORS - create movements from different kinds of curves public SilkwormMovement(Dictionary <string, string> Settings, Curve curve) { Polyline pline = new Polyline(); PolylineCurve plinec = new PolylineCurve(); if (curve.TryGetPolyline(out pline)) { } else { plinec = curve.ToPolyline(0, 0, 0.05, 0.1, 0, 0, 0.1, 0, true); //List<Curve> lines = plinec.DuplicateSegments().ToList(); List <Curve> lines = DuplicateSegments(plinec); List <Point3d> points = new List <Point3d>(); points.Add(lines[0].PointAtStart); foreach (Curve line in lines) { points.Add(line.PointAtEnd); } pline = new Polyline(points); } SilkwormMovement s_Movement = new SilkwormMovement(Settings, pline); sMovement = s_Movement.sMovement; Length = s_Movement.Length; Time = s_Movement.Time; ZDomain = s_Movement.ZDomain; complete = true; Configuration = Settings; //Add Lift Delimiter sDelimiter = new Type.Delimiter( double.Parse(Settings["retract_lift"]), double.Parse(Settings["retract_length"]), double.Parse(Settings["retract_restart_extra"]), double.Parse(Settings["retract_speed"]), double.Parse(Settings["travel_speed"])); }
//CUSTOM CONSTRUCTORS //Create a movement from a list of lines public SilkwormMovement(List <SilkwormLine> s_Movement, Delimiter s_Delimiter) { sMovement = s_Movement; sDelimiter = s_Delimiter; double eLengthAll = 0; double fTimeAll = 0; int isComplete = 0; //Check if Created Movement is Complete foreach (SilkwormLine line in s_Movement) { if (line.Speed == -1 || line.Flow == -1) { isComplete += 1; } else { eLengthAll += (line.sExtrusion); fTimeAll += (line.Speed * line.sLine.Length); } } if (isComplete == 0) { complete = true; } else { complete = false; } isPt = false; Length = eLengthAll; Time = fTimeAll; ZDomain = new Interval(s_Movement[0].sLine.FromZ, s_Movement[s_Movement.Count - 1].sLine.ToZ); //return sMovement; }
public SilkwormMovement(Dictionary <string, string> Settings, Polyline polyline) { List <Line> lines = polyline.GetSegments().ToList(); SilkwormMovement s_Movement = new SilkwormMovement(Settings, lines); sMovement = s_Movement.sMovement; Length = s_Movement.Length; Time = s_Movement.Time; ZDomain = s_Movement.ZDomain; complete = true; Configuration = Settings; //Add Lift Delimiter sDelimiter = new Type.Delimiter( double.Parse(Settings["retract_lift"]), double.Parse(Settings["retract_length"]), double.Parse(Settings["retract_restart_extra"]), double.Parse(Settings["retract_speed"]), double.Parse(Settings["travel_speed"])); }
//Method for displaying the contents of the model according to settings defined from Grasshopper public void displayModel(double startPrev, double endPrev, bool showmesh, int res, out List <Line> sLines, out List <double> lineThickness, out List <Line> DelimitMarkers, out List <Point3d> blobPoints, out List <double> blobDiameter, out List <Color> Colors, out Mesh sMesh, out List <Point3d> startPoints, out List <Point3d> endPoints) { List <Line> s_Lines = new List <Line>(); List <double> linethickness = new List <double>(); List <Line> delimitmarkers = new List <Line>(); List <Point3d> blobPts = new List <Point3d>(); List <double> blobdiameter = new List <double>(); Mesh s_Mesh = new Mesh(); //List<DisplayMaterial> d_Materials = new List<DisplayMaterial>(); List <Color> colors = new List <Color>(); List <SilkwormLine> silkLines = new List <SilkwormLine>(); List <Point3d> startPts = new List <Point3d>(); List <Point3d> endPts = new List <Point3d>(); int counter = 0; #region Find domain of preview int start = 0; int end = sModel.Count; if (startPrev >= 0.0 && endPrev <= 1.0) { start = (int)Math.Round((startPrev * end), 0); end = (int)Math.Round((endPrev * end), 0); } #endregion #region Find Range of Speed Values for Model double maxSpeed = travel_speed; double minSpeed = min_print_speed; foreach (SilkwormMovement move in sModel) { if (move.isGCode) { continue; } if (move.isPt) { continue; } foreach (SilkwormLine line in move.sMovement) { double Speed = line.Speed; maxSpeed = Math.Max(maxSpeed, Speed); } } foreach (SilkwormMovement move in sModel) { if (move.isGCode) { continue; } if (move.isPt) { continue; } foreach (SilkwormLine line in move.sMovement) { double Speed = line.Speed; minSpeed = Math.Min(minSpeed, Speed); } } #endregion #region Find Range of Flow Values for Model double maxFlow = 0; double minFlow = 0; foreach (SilkwormMovement move in sModel) { if (move.isGCode) { continue; } if (move.isPt) { double Flow = (move.sDelimiter.startPressure - move.sDelimiter.endPressure); maxFlow = Math.Max(maxFlow, Flow); continue; } foreach (SilkwormLine line in move.sMovement) { double Flow = line.Flow; maxFlow = Math.Max(maxFlow, Flow); } } foreach (SilkwormMovement move in sModel) { if (move.isGCode) { continue; } if (move.isPt) { double Flow = (move.sDelimiter.startPressure - move.sDelimiter.endPressure); minFlow = Math.Min(minFlow, Flow); continue; } foreach (SilkwormLine line in move.sMovement) { double Flow = line.Flow; minFlow = Math.Min(minFlow, Flow); } } #endregion #region Display from start to end for (int i = start; i < end; i++) { //Start Point of Movement Point3d startPt = new Point3d(); //End Point of Movement Point3d endPt = new Point3d(); if (!sModel[i].isPt) { startPt = sModel[i].sMovement[0].sLine.From; endPt = sModel[i].sMovement[sModel[i].sMovement.Count - 1].sLine.To; } //Skip if it is a custom GCode Movement if (sModel[i].isGCode) { continue; } //If it is a blob point if (sModel[i].isPt) { startPt = sModel[i].blobPoint; endPt = sModel[i].blobPoint; blobPts.Add(sModel[i].blobPoint); double blobvalue = (sModel[i].sDelimiter.startPressure + sModel[i].sDelimiter.endPressure); blobdiameter.Add(blobvalue); } #region Draw Start Delimiter if (i == 0) { Delimiter startDelimit = sModel[0].sDelimiter; //draw delimiter from origin to start of print - delimiter Point3d dPt = (new Point3d( startPt.X - startDelimit.startVec.X, startPt.Y - startDelimit.startVec.Y, startPt.Z - startDelimit.startVec.Z )); Line startLine = new Line(Plane.WorldXY.Origin, dPt); Line downLine = new Line(dPt, startPt); if (showmesh) { } //s_Lines.Add(startLine); //s_Lines.Add(downLine); delimitmarkers.Add(startLine); delimitmarkers.Add(downLine); //colors.Add(Color.FromArgb(128, 128, 128)); //colors.Add(Color.FromArgb(128, 128, 128)); //linethickness.Add(1); //linethickness.Add(1); counter += 1; } else if (i == start) { Delimiter startDelimit = sModel[i].sDelimiter; //draw start delimiter Point3d dPt = (new Point3d( startPt.X - startDelimit.startVec.X, startPt.Y - startDelimit.startVec.Y, startPt.Z - startDelimit.startVec.Z )); Line downLine = new Line(dPt, sModel[i].sMovement[0].sLine.From); if (showmesh) { } //s_Lines.Add(downLine); delimitmarkers.Add(downLine); //colors.Add(Color.FromArgb(128, 128, 128)); //linethickness.Add(1); counter += 1; } else { //draw line from end of last movement to start of this one Delimiter startDelimit = sModel[i].sDelimiter; Delimiter lastDelimit = sModel[i - 1].sDelimiter; Point3d lastPt = new Point3d(); if (!sModel[i - 1].isPt) { lastPt = sModel[i - 1].sMovement[sModel[i - 1].sMovement.Count - 1].sLine.To; } if (sModel[i - 1].isPt) { lastPt = sModel[i - 1].blobPoint; } if (sModel[i - 1].isGCode) { lastPt = startPt; } Point3d lastDPt = new Point3d( lastPt.X + lastDelimit.endVec.X, lastPt.Y + lastDelimit.endVec.Y, lastPt.Z + lastDelimit.endVec.Z ); Point3d dPt = (new Point3d( startPt.X - startDelimit.startVec.X, startPt.Y - startDelimit.startVec.Y, startPt.Z - startDelimit.startVec.Z )); Line startLine = new Line(lastDPt, dPt); Line downLine = new Line(dPt, startPt); if (showmesh) { } //s_Lines.Add(startLine); //s_Lines.Add(downLine); delimitmarkers.Add(startLine); delimitmarkers.Add(downLine); //colors.Add(Color.FromArgb(128, 128, 128)); //colors.Add(Color.FromArgb(128, 128, 128)); //linethickness.Add(1); //linethickness.Add(1); counter += 1; } #endregion #region Draw Movement //Only attempt if movement is not a point if (!sModel[i].isPt) { SilkwormMovement sMovement = sModel[i]; for (int p = 0; p <= sMovement.sMovement.Count - 1; p++) { //Silkworm Line Line sLine = sMovement.sMovement[p].sLine; silkLines.Add(sMovement.sMovement[p]); s_Lines.Add(sLine); //Flow Value double radius = sMovement.sMovement[p].Flow; //Speed Value double speedValue = sMovement.sMovement[p].Speed; //Create a Colour Value for the Faces of the Segment int colorValue = Convert.ToInt32((speedValue / maxSpeed) * 255); //Color faceColor = Color.FromArgb(colorValue, 0, 255 - colorValue); colors.Add(Color.FromArgb(colorValue, 0, 255 - colorValue)); ////Create Drawn thickness value int maxthickness = 10; int thickness = Convert.ToInt32(Math.Round(((radius / maxFlow) * maxthickness), MidpointRounding.AwayFromZero)); linethickness.Add(thickness); //increment counter += 1; } } #endregion #region Draw End Delimiter if (!sModel[i].sDelimiter.endVec.IsZero) { Delimiter endDelimit = sModel[i].sDelimiter; Point3d dPt = (new Point3d( endPt.X + endDelimit.endVec.X, endPt.Y + endDelimit.endVec.Y, endPt.Z + endDelimit.endVec.Z )); Line upLine = new Line(endPt, dPt); if (showmesh) { } //s_Lines.Add(upLine); delimitmarkers.Add(upLine); //colors.Add(Color.FromArgb(128, 128, 128)); //linethickness.Add(1); counter += 1; } #endregion startPts.Add(startPt); endPts.Add(endPt); } #endregion //Draw Mesh if (showmesh) { #region mesh model meshsLine(silkLines, res, out s_Mesh); //color mesh vertices s_Mesh.VertexColors.CreateMonotoneMesh(Color.White); for (Int32 g = res; g < s_Mesh.VertexColors.Count; g += res) { for (int h = 0; h < res; h++) { s_Mesh.VertexColors[g + h] = colors[(g / res) - 1]; } } #endregion } sLines = s_Lines; lineThickness = linethickness; DelimitMarkers = delimitmarkers; blobPoints = blobPts; blobDiameter = blobdiameter; sMesh = s_Mesh; Colors = colors; startPoints = startPts; endPoints = endPts; }
public SilkwormMovement(Dictionary <string, string> Settings, List <Line> lines) { double eLengthAll = 0; double fTimeAll = 0; SilkwormCalculator calc = new SilkwormCalculator(Settings); //Core Default Settings for extrusion flow and speed generated in here #region Build Silkworm Model from Geometry and Printer Settings //Output Holder List <SilkwormLine> sLines = new List <SilkwormLine>(); for (int i = 0; i < lines.Count; i++) { GH_Line sMove = new GH_Line(lines[i]); //if((GH_Line)MInnerArray[j-1] = null){return ;} GH_Line sMove_1 = new GH_Line(); if (i == 0) { sMove_1 = new GH_Line(lines[i]); } else { sMove_1 = new GH_Line(lines[i - 1]); } #region Extrusion Flow Module /* * Some Extrusion Calculation Guidelines (from Josef Prusa's Calculator: http://calculator.josefprusa.cz/) *-- WOH smaller than 2.0 produces weak parts * --WOH bigger than 3 decreases the detail of printed part, because of thick line * * layer height (LH)= height of each printed layer above the previous * width over height (WOH) = line width/ layer height * free extrusion diameter (extDia) = nozzle diamter + 0.08mm * line width (LW) = LH * WOH * free extrusion cross section area (freeExt) = (extDia/2)*(extDia/2)*Math.PI * minimal extrusion cross section area for stable extrusion (minExt) = freeExt*0.5 * Extruded line cross section area (extLine) = extLine = LW * LH; * Suggested bridge flow-rate multiplier = (freeExt*0.7)/extLine * Predicted smallest feature printable in XY = lineWidth/2 * angleHelp = Math.sqrt((lineWidth/2)*(lineWidth/2)+LH*LH) * angleHelp = Math.asin((lineWidth/2)/angleHelp) * Predicted maximim overhang angle = angleHelp * (180/Math.PI) */ double nozDia = double.Parse(Settings["nozzle_diameter"]); double filDia = double.Parse(Settings["filament_diameter"]); //Calculate Flow Rate as a Ratio of Filament Diameter to Nozzle Diameter double FlM = ((Math.Pow(nozDia / 2, 2) * Math.PI) / (Math.Pow(filDia / 2, 2) * Math.PI)); //double FlM = 0.66; #endregion #region Print Feedrate Module Line line = sMove.Value; Line line_1 = sMove_1.Value; Vector3d vecA = line.Direction; Vector3d vecA_1 = line_1.Direction; Arc arc = new Rhino.Geometry.Arc(line_1.From, vecA_1, line.To); //double vecAngle = Rhino.Geometry.Vector3d.VectorAngle(vecA, vecA_1); //Speed on an Arc = sqrt((Accel * Radius) / sqrt(2)) double accel = double.Parse(Settings["perimeter_acceleration"]); double fRate = ( Math.Max( Math.Min( Math.Sqrt((accel * arc.Radius) / (Math.Sqrt(2))), double.Parse(Settings["perimeter_speed"])), double.Parse(Settings["min_print_speed"])) * 60); //Start speed as perimeter speed if (i == 0) { fRate = double.Parse(Settings["perimeter_speed"]) * 60; } #endregion sLines.Add(new SilkwormLine(FlM, fRate, line)); } #endregion //Property Assignment sMovement = sLines; Length = eLengthAll; Time = fTimeAll; ZDomain = new Interval(sLines[0].sLine.FromZ, sLines[sLines.Count - 1].sLine.ToZ); complete = true; Configuration = Settings; //Add Lift Delimiter sDelimiter = new Type.Delimiter( double.Parse(Settings["retract_lift"]), double.Parse(Settings["retract_length"]), double.Parse(Settings["retract_restart_extra"]), double.Parse(Settings["retract_speed"]), double.Parse(Settings["travel_speed"])); }