/// <summary> /// Длина /// </summary> /// <param name="curve"></param> /// <returns></returns> public static double GetLength(this DBObject curve) { if (curve == null) { return(0); } if (curve is Line) { return((curve as Line).Length); } if (curve is Arc) { return((curve as Arc).Length); } if (curve is Circle) { return((curve as Circle).Diameter * Math.PI); } if (curve is Polyline) { return((curve as Polyline).Length); } if (curve is Polyline2d) { return((curve as Polyline2d).Length); } AutocadUtils.ShowError("Неподдерживаемый тип кривой"); return(0); }
/// <summary> /// Расчет обработки /// </summary> public static List <ProcessingAction> Generate(IEnumerable <ProcessObject> processObjects, List <Curve> sectionCurves) { try { IsCalculation = true; AutocadUtils.StartTransaction(); Machine.Start(); foreach (var processObject in processObjects) { if (!IsCalculation) { break; } if (!CheckParams(processObject)) { continue; } Machine.SetTool(processObject.Tool); if (processObject.Curve.OutsideSign == 0) { CalcUtils.CalcOutside(processObject.Curve); } var curve = AutocadUtils.GetCurve(processObject.Curve.ObjectId); if (Settings.ProcessMode == ProcessMode.ContinuousDescent) { if (!curve.Closed) { throw new Exception("Расчет в режиме непрерывного опускания возможен только для замкнутой кривой"); } CuttingContinuousDescent(processObject, curve); } else if (Settings.ProcessMode == ProcessMode.ProfileDisc) { CuttingProfileDisc(processObject, curve, sectionCurves); } else { Cutting(processObject, curve); } } Machine.Stop(); AutocadUtils.CommitTransaction(); } catch (Exception e) { Machine.Clear(); var error = String.Format("Ошибка при расчете обработки: {0}", e.Message); AutocadUtils.ShowError(error); } AutocadUtils.DisposeTransaction(); IsCalculation = false; return(Machine.GetProcessingActions()); }
/// <summary> /// Удалить обработку /// </summary> private void DeleteProcessing() { if (ActionGenerator.IsCalculation) { ActionGenerator.Abort(); AutocadUtils.ShowError("Расчет обработки прерван"); return; } if (ProcessingActions == null) { return; } AutocadUtils.DeleteCurves(ProcessingActions.ConvertAll(p => p.ObjectId)); AutocadUtils.DeleteCurves(ProcessingActions.ConvertAll(p => p.DirectObjectId)); AutocadUtils.DeleteCurves(ProcessingActions.ConvertAll(p => p.ToolObjectId)); ProcessingActions.Clear(); ProcessingForm.ShowData(ProcessingActions); }
private static void CuttingProfileDisc(ProcessObject processObject, Curve curve, List <Curve> sectionCurves) { if (sectionCurves.Count == 0) { AutocadUtils.ShowError("Не указано сечение"); return; } var par = processObject.ProcessingParams; var z = Settings.HeightMax; do { if (!IsCalculation) { return; } var d1 = CalcUtils.GetSectionDepth(sectionCurves, z); var d2 = CalcUtils.GetSectionDepth(sectionCurves, z - processObject.Tool.Thickness.GetValueOrDefault()); double d; if (d1.HasValue && d2.HasValue) { d = d1 > d2 ? d1.Value : d2.Value; } else if (d1.HasValue) { d = d1.Value; } else if (d2.HasValue) { d = d2.Value; } else { return; } var toolpathCurve = AutocadUtils.GetDisplacementCopy(curve, z); AlternatingCuttingCurve(processObject, toolpathCurve, d + Settings.Pripusk); z -= Settings.VerticalStep; }while (z >= Settings.HeightMin); }
private static bool CheckParams(ProcessObject processObject) { var par = processObject.ProcessingParams; var error = String.Empty; if ((Settings.ProcessMode == ProcessMode.StepByStepDescent || Settings.ProcessMode == ProcessMode.ContinuousDescent) && Settings.Thickness < 0.1) { error = "укажите толщину"; } if (Settings.ProcessMode == ProcessMode.ContinuousDescent && par.DepthAll == 0) { error = "укажите суммарную глубину"; } if (par.DepthAll > 0 && par.Depth < 0.1) { error = "укажите шаг"; } if (!String.IsNullOrEmpty(error)) { AutocadUtils.ShowError(String.Format("Объект {0}: {1}", processObject.Curve.Name, error)); } return(String.IsNullOrEmpty(error)); }
public static List <string> Generate(IEnumerable <ProcessingAction> actions) { Settings = Settings.GetInstance(); MachineProgram.Clear(); _lineNo = 0; foreach (var action in actions) { switch (action.ActionType) { // Начало программы case ActionType.StartOfProgram: AddLine("; Start of Program \"" + Settings.MachineName + "\""); AddLine(";"); AddLine("; PART NAME :"); AddLine("; DATE TIME : " + DateTime.Now); AddLine(";"); if (Settings.Machine == MachineKind.Krea) { AddLine("(UAO,E30)"); AddLine("(UIO,Z(E31))"); } if (Settings.Machine == MachineKind.Ravelli) { AddLine("G54G17G90G642"); AddLine("G0G90G153D0Z0"); } break; // Конец программы case ActionType.EndOfProgram: AddLine("; End of Program"); AddLine("M30"); break; // Плоскость обработки case ActionType.PlaneProcessing: AddLine("G17"); break; // Смена инструмента case ActionType.ChangeTool: AddLine("; Start of Path"); AddLine(";"); AddLine("; Tool Change"); var par = action.Param.Split(';'); AddLine("T" + (par.Any() ? par[0] : "?")); if (Settings.Machine == MachineKind.Ravelli) { AddLine("M6"); AddLine("D" + (par.Count() > 1 ? par[1] : "?")); AddLine("G54"); AddLine("G0 B0 C0"); } break; // Включение шпинделя case ActionType.SpindleStart: AddLine(String.Format("S{0} M3", action.Param)); AddLine("M7"); AddLine("M8"); break; // Выключение шпинделя case ActionType.SpindleStop: AddLine("; End of Path"); AddLine("M5"); // выключение шпинделя if (Settings.Machine == MachineKind.Krea) { AddLine("M9 M10"); // выключение воды AddLine("G0 G79 Z(@ZUP)"); // подъем в верхнюю точку } if (Settings.Machine == MachineKind.Ravelli) { AddLine("M9"); AddLine("G0G90G153D0Z0"); } break; // Компенсация case ActionType.Compensation: AddLine(action.CompensationSide == CompensationSide.Left ? "G41" : (action.CompensationSide == CompensationSide.Right ? "G42" : "G40")); break; // Подвод к точке опускания, Перемещение инструмента, Опускание инструмента, Подъем инструмента // Заход, Резка, Выход, Опускание инструмента, Подъем инструмента case ActionType.InitialMove: case ActionType.Move: case ActionType.EngageMove: case ActionType.Cutting: case ActionType.RetractMove: case ActionType.AapproachMove: case ActionType.DepartureMove: AddGCommand(action); break; default: AutocadUtils.ShowError(String.Format("Ошибка при генерации программы: не распознана команда \"{0}\"", action.ActionType)); break; } } return(MachineProgram); }
/// <summary> /// Движение инструмента по траектории /// </summary> /// <param name="actionType">Тип действия</param> /// <param name="path">Траектория</param> private ProcessingAction PathMovement(ActionType actionType, Curve path, int?speed = null) { if (path == null) { return(null); } var oldPosition = _position; if ((_position == path.StartPoint) || (Math.Abs(_position.X - path.StartPoint.X) < CalcUtils.Tolerance) && (Math.Abs(_position.Y - path.StartPoint.Y) < CalcUtils.Tolerance)) { _position = path.EndPoint; } else if ((_position == path.EndPoint) || (Math.Abs(_position.X - path.EndPoint.X) < CalcUtils.Tolerance) && (Math.Abs(_position.Y - path.EndPoint.Y) < CalcUtils.Tolerance)) { _position = path.StartPoint; } else { AutocadUtils.ShowError("Ошибка: не соответствие позиции при расчете траектории"); return(null); } var action = CreateProcessAction(actionType, speed: speed); action.ObjectId = path.ObjectId != ObjectId.Null ? path.ObjectId : AutocadUtils.AddCurve(path, actionType); action.DirectObjectId = SetDirectLine(path); SetCoordinates(action, oldPosition, _position, path is Arc); if (path is Line) { action.ToolpathCurveType = ToolpathCurveType.Line; } if (path is Arc) { var arc = path as Arc; action.ToolpathCurveType = (_position == arc.StartPoint ? ToolpathCurveType.ArcClockwise : ToolpathCurveType.ArcCounterclockwise); if (action.ToolpathCurveType == ToolpathCurveType.ArcClockwise ^ _compensation == CompensationSide.Left) // инструмент внутри дуги { if (arc.Radius <= _tool.Diameter / 2) { action.Note = "Радиус дуги меньше или равен радиусу инструмента"; action.IsError = true; var message = String.Format("Строка {0}: {1}", action.No, action.Note); AutocadUtils.ShowError(message); } if (arc.Radius <= 1.5 * _tool.Diameter) { action.Speed = 200; _isSpeedChanged = true; } } action.I = Round(arc.Center.X); action.J = Round(arc.Center.Y); var vector = oldPosition.GetVectorTo(arc.Center); action.Irel = Round(vector.X); action.Jrel = Round(vector.Y); } action.Param = action.ToolpathCurveType.ToString(); return(action); }
public static FeedGroup CalcFeedGroup(Curve curve, bool isStartCurve, int sign, FeedType feedType, int radius, int angle, int length) { var feedGroup = new FeedGroup(); Vector3d vector; Point3d point = isStartCurve ? curve.StartPoint : curve.EndPoint; if (!curve.Closed || isStartCurve) { vector = curve.GetFirstDerivative(point); } else if (curve is Circle) { vector = new Vector3d(0, 1, 0); } else // расчет касательной в конце замкнутой полилинии { int param; var polyline = curve as Polyline; if (polyline != null) { param = polyline.NumberOfVertices - 1; } else { var polyline2d = curve as Polyline2d; if (polyline2d != null) { param = polyline2d.Cast <object>().Count(); } else { AutocadUtils.ShowError("Ошибка в расчете подвода-отвода"); feedGroup.Point = point; return(feedGroup); } } vector = curve.GetFirstDerivative(param); } switch (feedType) { case FeedType.None: feedGroup.Point = point; break; case FeedType.Line: vector = (isStartCurve ? -1 : 1) * vector.GetNormal() * length; feedGroup.Point = point + vector; feedGroup.Line = new Line(point, feedGroup.Point); break; case FeedType.Arc: vector = vector.GetPerpendicularVector() * sign * radius; feedGroup.Point = point + vector; vector = vector.Negate(); var angle1 = vector.GetAngleTo(Vector3d.XAxis, Vector3d.ZAxis.Negate()); var turnSign = (isStartCurve ? -1 : 1) * sign; vector = vector.RotateBy(DegreesToRadians(angle) * turnSign, Vector3d.ZAxis); feedGroup.Line = new Line(feedGroup.Point, feedGroup.Point + vector); var angle2 = feedGroup.Line.Angle; var isCrossAxis = Math.Abs(angle2 - angle1) > Pi; feedGroup.Arc = new Arc(feedGroup.Point, radius, isCrossAxis ? Math.Max(angle1, angle2) : Math.Min(angle1, angle2), isCrossAxis ? Math.Min(angle1, angle2) : Math.Max(angle1, angle2)); break; } return(feedGroup); }