Esempio n. 1
0
        private void Cutting(MillingCommandGenerator generator, double x, double y)
        {
            generator.Move(x, y);
            generator.Move(z: ZEntry);
            var    zMin    = -Depth;
            double z       = 0;
            int    counter = 0;

            while (z >= zMin)
            {
                var feed = (int)((FeedMax - FeedMin) / zMin * (z * z / zMin - 2 * z) + FeedMax);
                generator.Cutting(x, y, z, feed);
                if (z <= -2)
                {
                    if (++counter == 5) // Подъем на 1мм для охлаждения
                    {
                        counter = 0;
                        generator.Pause(0.2);
                        generator.Uplifting(z + 1);
                        generator.Cutting(x, y, z + 0.2, (int)(FeedMax * 1.5));
                        generator.Cutting(x, y, z, feed);
                    }
                }
                z -= 0.2;
            }
            generator.Pause(0.2);
            generator.Uplifting();
        }
Esempio n. 2
0
        private Point3d BuildPass(MillingCommandGenerator generator, List <Point3d> points)
        {
            var  z = generator.ZSafety - TechProcess.ZSafety;
            bool isComplete;
            var  point = Algorithms.NullPoint3d;

            do
            {
                isComplete = true;
                z         -= Penetration;
                var point0 = Algorithms.NullPoint3d;

                foreach (var pt in points)
                {
                    var p = pt;
                    if (z > p.Z)
                    {
                        p          = new Point3d(p.X, p.Y, z);
                        isComplete = false;
                    }
                    if (generator.IsUpperTool)
                    {
                        generator.Move(p.X, p.Y, angleC: ((Disk3DTechProcess)TechProcess).Angle);
                        generator.Cycle();
                    }
                    if (point.IsNull())
                    {
                        if (generator.ToolPosition.Point != p)
                        {
                            generator.GCommand(CommandNames.Penetration, 1, point: p, feed: TechProcess.PenetrationFeed);
                        }
                        else
                        {
                            generator.Move(p.X, p.Y);
                            generator.Cycle();
                        }
                    }
                    else if (point0 != point && point != p && !point0.GetVectorTo(point).IsCodirectionalTo(point.GetVectorTo(p)))
                    {
                        generator.GCommand(CommandNames.Cutting, 1, point: point, feed: CuttingFeed);
                        point0 = point;
                    }
                    if (point0.IsNull())
                    {
                        point0 = p;
                    }
                    point = p;
                }
                generator.GCommand(CommandNames.Cutting, 1, point: point, feed: CuttingFeed);
                points.Reverse();
            }while (!isComplete);

            if (IsUplifting)
            {
                generator.Uplifting();
            }

            return(point);
        }
Esempio n. 3
0
        private Point3d BuildPassA90(MillingCommandGenerator generator, List <Point3d> points, Matrix3d matrix, double z0)
        {
            var  z = z0;
            bool isComplete;
            var  point = Algorithms.NullPoint3d;

            do
            {
                isComplete = true;
                z         -= Penetration;
                var point0 = Algorithms.NullPoint3d;
                point = Algorithms.NullPoint3d;
                //var isPassStarted = false;

                foreach (var pt in points)
                {
                    var p = pt;
                    if (z > p.Z)
                    {
                        p          = new Point3d(p.X, p.Y, z);
                        isComplete = false;
                    }
                    if (generator.IsUpperTool)
                    {
                        generator.Move(p, angleC: TechProcess.Angle, angleA: 90);
                        generator.Cycle();
                    }
                    if (point.IsNull())
                    {
                        if (generator.ToolPosition.Point != p.TransformBy(matrix))
                        {
                            generator.GCommand(CommandNames.Penetration, 1, point: p, feed: TechProcess.PenetrationFeed);
                        }
                        else
                        {
                            generator.Move(p, angleA: 90);
                            generator.Cycle();
                        }
                    }
                    else if (point0 != point && point != p && !point0.GetVectorTo(point).IsCodirectionalTo(point.GetVectorTo(p)))
                    {
                        generator.GCommand(CommandNames.Cutting, 1, point: point, feed: CuttingFeed);
                        point0 = point;
                    }
                    if (point0.IsNull())
                    {
                        point0 = p;
                    }
                    point = p;
                }
                generator.GCommand(CommandNames.Cutting, 1, point: point, feed: CuttingFeed);
                points.Reverse();
            }while (!isComplete);

            //generator.Move(point.Add(Vector3d.ZAxis * 100));
            return(point);
        }
Esempio n. 4
0
        private void BuildPass(MillingCommandGenerator generator, List <Point3d> points)
        {
            var point0 = Algorithms.NullPoint3d;
            var point  = Algorithms.NullPoint3d;

            foreach (var p in points)
            {
                if (generator.IsUpperTool)
                {
                    generator.Move(p.X, p.Y, angleC: ((Disk3DTechProcess)TechProcess).Angle);
                }

                if (point.IsNull())
                {
                    if (generator.ToolPosition.Point != p)
                    {
                        generator.GCommand(CommandNames.Penetration, 1, point: p, feed: TechProcess.PenetrationFeed);
                    }
                }
                else if (point0 != point && point != p && !point0.GetVectorTo(point).IsCodirectionalTo(point.GetVectorTo(p)))
                {
                    generator.GCommand(CommandNames.Cutting, 1, point: point, feed: CuttingFeed);
                    point0 = point;
                }
                if (point0.IsNull())
                {
                    point0 = p;
                }
                point = p;
            }
            generator.GCommand(CommandNames.Cutting, 1, point: point, feed: CuttingFeed);
        }
Esempio n. 5
0
        public override void BuildProcessing(MillingCommandGenerator generator)
        {
            const int AngleA             = 45;
            var       tactileTechProcess = (TactileTechProcess)TechProcess;
            var       contour            = tactileTechProcess.GetContour();
            var       contourPoints      = contour.GetPolyPoints().ToArray();
            var       ray = new Ray
            {
                BasePoint = ProcessingAngle == 45 ? contourPoints.Last() : contourPoints.First(),
                UnitDir   = Vector3d.XAxis.RotateBy(Graph.ToRad(ProcessingAngle), Vector3d.ZAxis)
            };
            var passDir = ray.UnitDir.GetPerpendicularVector();

            if (ProcessingAngle >= 90)
            {
                passDir = passDir.Negate();
            }
            ray.BasePoint += passDir * (tactileTechProcess.BandStart1.Value - tactileTechProcess.BandSpacing.Value);
            var step       = tactileTechProcess.BandWidth.Value + tactileTechProcess.BandSpacing.Value;
            var engineSide = ProcessingAngle < 90 ? Side.Right : Side.Left;

            while (true)
            {
                var points = new Point3dCollection();
                ray.IntersectWith(contour, Intersect.ExtendThis, new Plane(), points, IntPtr.Zero, IntPtr.Zero);
                if (points.Count == 2 && !points[0].IsEqualTo(points[1]))
                {
                    var vector     = (points[1] - points[0]).GetNormal() * tactileTechProcess.Departure;
                    var startPoint = points[0] - vector - Vector3d.ZAxis * tactileTechProcess.Depth;
                    var endPoint   = points[1] + vector - Vector3d.ZAxis * tactileTechProcess.Depth;
                    if (generator.IsUpperTool)
                    {
                        generator.Move(startPoint.X, startPoint.Y, angleC: BuilderUtils.CalcToolAngle(ProcessingAngle.ToRad(), engineSide), angleA: AngleA);
                    }
                    generator.Cutting(startPoint, endPoint, CuttingFeed, tactileTechProcess.TransitionFeed);
                }
                else if (step > 0)
                {
                    ray.BasePoint += passDir * tactileTechProcess.BandSpacing.Value;
                    step           = -step;
                    generator.Uplifting();
                    engineSide = engineSide.Opposite();
                }
                else
                {
                    break;
                }
                ray.BasePoint += passDir * step;
            }
        }
Esempio n. 6
0
        public override void BuildProcessing(MillingCommandGenerator generator)
        {
            var tactileTechProcess = (TactileTechProcess)TechProcess;
            var isDiag             = tactileTechProcess.ProcessingAngle1 != 0;

            var contour       = tactileTechProcess.GetContour();
            var contourPoints = contour.GetPolyPoints().ToArray();

            var point = tactileTechProcess.Objects.Select(p => p.GetCurve()).OfType <Circle>().Select(p => p.Center).OrderBy(p => (int)p.Y).ThenBy(p => p.X).First();
            var x     = point.X;
            var y     = point.Y;
            var stepX = tactileTechProcess.BandSpacing.Value + tactileTechProcess.BandWidth.Value;
            var stepY = stepX;

            if (isDiag)
            {
                stepY /= Math.Sqrt(2);
                stepX  = stepY * 2;
            }
            generator.SetTool(2, Frequency, 90, false);
            generator.ZSafety = ZSafety;

            while (y < contourPoints[1].Y)
            {
                Cutting();
                x += stepX;
                if (x > contourPoints[3].X)
                {
                    y    += stepY;
                    x    -= stepY;
                    stepX = -stepX;
                    if (x > contourPoints[3].X)
                    {
                        x += stepX;
                    }
                }
                if (x < contourPoints[1].X)
                {
                    y    += stepY;
                    x    += stepY;
                    stepX = -stepX;
                    if (x < contourPoints[1].X)
                    {
                        x += stepX;
                    }
                }
            }

            void Cutting()
            {
                generator.Move(x, y);
                generator.Move(z: ZEntry);
                var    zMin    = -Depth;
                double z       = 0.2;
                int    counter = 0;

                while (z > zMin)
                {
                    z -= 0.2;
                    if (z < zMin)
                    {
                        z = zMin;
                    }

                    var feed = (int)((FeedMax - FeedMin) / zMin * (z * z / zMin - 2 * z) + FeedMax);
                    generator.Cutting(x, y, z, feed);
                    if (z <= -2)
                    {
                        if (++counter == 5) // Подъем на 1мм для охлаждения
                        {
                            counter = 0;
                            Pause();
                            generator.Uplifting(z + 1);
                            generator.Cutting(x, y, z + 0.2, (int)(FeedMax * 1.5));
                            generator.Cutting(x, y, z, feed);
                        }
                    }
                }
                Pause();
                generator.Uplifting();

                void Pause() => generator.Command("G4 F0.2", "Пауза");
            }

            contour.Dispose();
        }
Esempio n. 7
0
        public override void BuildProcessing(MillingCommandGenerator generator)
        {
            var railBase    = TechProcess.Rail?.GetCurve() ?? new Line(Point3d.Origin, Point3d.Origin + Vector3d.XAxis * TechProcess.Length.Value);
            var profile     = (Profile ?? TechProcess.ProcessingArea[0]).GetCurve();
            var processSide = ChangeEngineSide ? -1 : 1;

            CreateProfile3D(profile, railBase, 1);
            //var processSide = ChangeProcessSide ? -1 : 1;
            //CreateProfile3D(profile, railBase, processSide);

            var rail = CreateDepartureRail(railBase, Departure);

            if (Delta != 0)
            {
                var profileOffset = (Curve)profile.GetOffsetCurves(Delta)[0];
                profile = profileOffset.EndPoint.GetAsVector().Length < profile.EndPoint.GetAsVector().Length
                    ? (Curve)profile.GetOffsetCurves(-Delta)[0]
                    : profileOffset;
                CreateProfile3D(profile, railBase, processSide);
            }
            if (!(railBase is Line))
            {
                processSide *= -1;
            }
            if (railBase.IsNewObject)
            {
                railBase.Dispose();
            }

            var side = BuilderUtils.CalcEngineSide(rail.GetFirstDerivative(0).GetAngleTo(Vector3d.XAxis));

            if (ChangeEngineSide)
            {
                side = SideExt.Opposite(side);
            }
            var isMinToolCoord = IsA90
                ? TechProcess.MachineType.Value != MachineType.ScemaLogic
                : side == Side.Right ^ TechProcess.MachineType.Value == MachineType.ScemaLogic ^ ChangeProcessSide;

            generator.CuttingFeed = CuttingFeed;
            generator.SmallFeed   = TechProcess.PenetrationFeed;
            generator.EngineSide  = side;

            Curve outletCurve = null;

            if (IsA90 && IsOutlet)
            {
                outletCurve = rail.GetOffsetCurves(TechProcess.ZSafety * processSide)[0] as Curve;
                var angleC = BuilderUtils.CalcToolAngle(outletCurve, outletCurve.StartPoint, side);
                generator.Move(outletCurve.StartPoint.X, outletCurve.StartPoint.Y, angleC: angleC, angleA: 90);
            }
            var angleA = IsA90 ? 90 : 0;
            var index  = IsA90 ? 1 : 0;

            var points = BuilderUtils.GetProcessPoints(profile, index, StepPass, TechProcess.Tool.Thickness.Value, isMinToolCoord, FirstPass, LasttPass, IsExactlyBegin, IsExactlyEnd, IsProfileStep);

            foreach (var point in points)
            {
                var end   = Math.Max(point[1 - index], PenetrationEnd ?? double.MinValue);
                var count = 1;
                var penetrationStepCalc = 0D;
                if (PenetrationStep.GetValueOrDefault() > 0 && PenetrationBegin.GetValueOrDefault() > end)
                {
                    var allPenetration = PenetrationBegin.Value - end;
                    count = (int)Math.Ceiling(allPenetration / PenetrationStep.Value);
                    penetrationStepCalc = allPenetration / count;
                }
                if (IsA90 && IsOutlet && generator._isEngineStarted)
                {
                    generator.Transition(z: point[index]);
                }

                var coords = Enumerable.Range(1, count).Select(p => end + (count - p) * penetrationStepCalc).ToList();
                if (IsA90)
                {
                    coords.ForEach(p => generator.Cutting(rail, processSide * p, point[index], angleA: angleA));
                }
                else
                {
                    coords.ForEach(p => generator.Cutting(rail, processSide * point[index], p, angleA: angleA));
                }

                if (IsOutlet)
                {
                    if (IsA90)
                    {
                        var pt = outletCurve.GetClosestPoint(generator.ToolPosition.Point);
                        generator.Move(pt.X, pt.Y);
                    }
                    else
                    {
                        generator.Uplifting();
                    }
                }
            }
            rail.Dispose();
        }
Esempio n. 8
0
        protected override void BuildProcessing(MillingCommandGenerator generator)
        {
            generator.ZSafety = ZSafety;
            if (MachineType.Value == CAM.MachineType.Donatoni)
            {
                generator.SetTool(2, Frequency, angleA: 90, hasTool: false);
            }
            else
            {
                generator.SetTool(1, Frequency, angleA: 0, hasTool: false);
            }

            var curves    = ProcessingArea.Select(p => p.ObjectId).QOpenForRead <Curve>().ToList();
            var bounds    = ProcessingArea.Select(p => p.ObjectId).GetExtents();
            var random    = new Random();
            var mainDir   = Vector3d.XAxis.RotateBy(Angle1.ToRad(), Vector3d.ZAxis);
            var side      = 1;
            var sign      = -1;
            var basePoint = bounds.MinPoint + (bounds.GetCenter() - bounds.MinPoint).GetNormal() * 100;

            using (var ray = new Ray())
                while (true)
                {
                    ray.BasePoint = basePoint;
                    ray.UnitDir   = mainDir.RotateBy(Angle2.ToRad() * side, Vector3d.ZAxis);
                    var points = ray.Intersect(curves).FindAll(p => p.DistanceTo(ray.BasePoint) > 10);
                    if (!points.Any())
                    {
                        break;
                    }

                    basePoint = points.First() + ray.UnitDir.Negate();
                    Cutting(ray.BasePoint, basePoint, ray.UnitDir, ray.UnitDir.GetPerpendicularVector() * side * sign);
                    side *= -1;
                }

            void Cutting(Point3d point1, Point3d point2, Vector3d dir, Vector3d pv)
            {
                var z = 0;

                if (generator.IsUpperTool)
                {
                    generator.Move(point1.X, point1.Y);
                    generator.GCommand(CommandNames.Cutting, 1, x: point1.X, y: point1.Y, z: ZEntry, feed: Feed / 5);
                    z = ZEntry;
                }
                var point0  = point1;
                var line    = new Line();
                var length  = point1.DistanceTo(point2);
                var l       = 0D;
                var a       = 0D;
                var count   = 10D;
                var stepA   = Math.PI / count;
                var stepL   = 0D;
                var amp     = 0;
                var isInner = true;

                while (l < length)
                {
                    if (Math.Abs(Math.Sin(a)) < Consts.Epsilon)
                    {
                        stepL = random.Next(StepMin, StepMax) / count;
                        amp   = random.Next(AmplitudeMin, AmplitudeMax);
                    }
                    l += stepL;
                    a += stepA;
                    var point = point1 + dir * l + pv * Math.Sin(a) * amp;
                    line.StartPoint = point0;
                    line.EndPoint   = point;
                    if (line.Intersect(curves).Any())
                    {
                        isInner = !isInner;
                    }
                    if (isInner)
                    {
                        if (z > 0)
                        {
                            z--;
                        }
                        generator.GCommand(CommandNames.Cutting, 1, x: point.X, y: point.Y, z: z, feed: Feed);
                    }
                    point0 = point;
                }
                line.Dispose();
                if (Math.Sin(a - stepA) > 0)
                {
                    sign = -sign;
                }
            }

            //var ray = new Ray
            //{
            //    BasePoint = new Point3d(bounds.MinPoint.X, 0, 0),
            //    UnitDir = Vector3d.YAxis
            //};
            //var uppDir = true;
            //var random = new Random();

            //while (true)
            //{
            //    var points = ray.Intersect(ProcessingArea.Select(p => p.ObjectId).QOpenForRead<Curve>().ToList(), Intersect.ExtendThis);
            //    if (points.Count == 0)
            //        break;
            //    if (points.Count > 1)
            //    {
            //        points = (uppDir ? points.OrderBy(p => p.Y) : points.OrderByDescending(p => p.Y)).ToList();
            //        Cutting(points.First(), points.Last());
            //    }
            //    ray.BasePoint += Vector3d.XAxis * Step1;
            //}

            //void Cutting(Point3d point1, Point3d point2)
            //{
            //    if (generator.IsUpperTool)
            //        generator.Move(point1.X, point1.Y);
            //    generator.GCommand(CommandNames.Cutting, 1, point: point1);

            //    var length = point1.DistanceTo(point2);
            //    var rnd = IsRandomStepCount ? (random.NextDouble() / 2 + 0.75) : 1;
            //    var countCycles = (int)Math.Round(length * rnd / Step2 / 2) * 2;
            //    var coodrs = Enumerable.Range(1, countCycles).Select(p => (double)p);
            //    if (IsRandomStepParams)
            //        coodrs = coodrs.Select(p => p + (p != countCycles ? (random.NextDouble() / 2 - 0.25) : 0));
            //    var coordArray = coodrs.ToArray();
            //    double l = 0;
            //    double a = 0;
            //    var count = 10;
            //    var stepA = Math.PI / count;
            //    for (int i = 0; i < coordArray.Length; i++)
            //    {
            //        var coord0 = i > 0 ? coordArray[i - 1] : 0;
            //        var dl = coordArray[i] - coord0;
            //        var stepL = dl * length / countCycles / count;

            //        foreach (var j in Enumerable.Range(1, count))
            //        {
            //            l += stepL;
            //            a += stepA;
            //            var point = point1 + new Vector3d(Math.Sin(a) * Amplitude * dl, uppDir ? l : -l, 0);
            //            generator.GCommand(CommandNames.Cutting, 1, point: point, feed: Feed);
            //        }
            //    }

            //while(true)
            //{
            //    cnt++;
            //    if (length - l < 2 * Step2)
            //    {

            //    }
            //    var rnd = random.Next(5, 10) / 10D;
            //    foreach (var i in Enumerable.Range(0, 10))
            //    {
            //        var point = point1 + new Vector3d(Math.Sin(a) * Amplitude * rnd, uppDir ? l : -l, 0);
            //        generator.GCommand(CommandNames.Cutting, 1, point: point, feed: Feed);
            //        l += stepL / 10 * rnd;
            //        a += stepA / 10;
            //    }
            //}


            //foreach (var i in Enumerable.Range(0, count))
            //{
            //    var point = point1 + new Vector3d(Math.Sin(a) * Amplitude, uppDir ? l : -l, 0);
            //    generator.GCommand(CommandNames.Cutting, 1, point: point, feed: Feed);
            //    l += stepL;
            //    a += stepA;
            //}
            //    uppDir = !uppDir;
            //}
        }
Esempio n. 9
0
        public override void BuildProcessing(MillingCommandGenerator generator)
        {
            var railBase    = TechProcess.Rail?.GetCurve() ?? new Line(Point3d.Origin, Point3d.Origin + Vector3d.XAxis * TechProcess.Length.Value);
            var profile     = (Profile ?? TechProcess.ProcessingArea[0]).GetCurve();
            var processSide = ChangeProcessSide ? 1 : -1;

            CreateProfile3D(profile, railBase, processSide);

            var rail = CreateDepartureRail(railBase, Departure);

            if (Delta != 0)
            {
                var profileOffset = (Curve)profile.GetOffsetCurves(Delta)[0];
                profile = profileOffset.EndPoint.GetAsVector().Length < profile.EndPoint.GetAsVector().Length
                    ? (Curve)profile.GetOffsetCurves(-Delta)[0]
                    : profileOffset;
                CreateProfile3D(profile, railBase, processSide);
            }
            var offsetSign = processSide * (railBase is Line ? 1 : -1);

            if (railBase.IsNewObject)
            {
                railBase.Dispose();
            }

            var side = BuilderUtils.CalcEngineSide(rail.GetFirstDerivative(0).GetAngleTo(Vector3d.XAxis));

            if (ChangeEngineSide)
            {
                side = SideExt.Opposite(side);
            }
            var isMinToolCoord = IsA90
                ? TechProcess.MachineType.Value != MachineType.ScemaLogic
                : side == Side.Right ^ TechProcess.MachineType.Value == MachineType.ScemaLogic ^ ChangeProcessSide;

            generator.CuttingFeed = CuttingFeed;
            generator.SmallFeed   = TechProcess.PenetrationFeed;
            generator.EngineSide  = side;

            Curve outletCurve = null;

            if (IsA90 && IsOutlet)
            {
                outletCurve = rail.GetOffsetCurves(TechProcess.ZSafety * offsetSign)[0] as Curve;
                var angleC = BuilderUtils.CalcToolAngle(outletCurve, outletCurve.StartPoint, side);
                generator.Move(outletCurve.StartPoint.X, outletCurve.StartPoint.Y, angleC: angleC, angleA: 90);
            }
            var angleA = IsA90 ? 90 : 0;
            var index  = IsA90 ? 1 : 0;

            var profilePoints = BuilderUtils.GetProcessPoints(profile, index, ProfileStep, TechProcess.Tool.Thickness.Value, isMinToolCoord, ProfileBegin, ProfileEnd, IsExactlyBegin, IsExactlyEnd, true);

            var profilePline = new Polyline();

            Enumerable.Range(0, profilePoints.Count).ForEach(i => profilePline.AddVertexAt(i, profilePoints[i], 0, 0, 0));

            var railLength = rail.Length();

            Acad.SetLimitProgressor((int)(railLength / LongStep));

            for (double dist = 0; dist < railLength; dist += LongStep)
            {
                Acad.ReportProgressor();

                var point     = rail.GetPointAtDist(dist);
                var angleC    = BuilderUtils.CalcToolAngle(rail, point, side);
                var passPline = CalcPassPline(rail, point, profilePline, processSide);

                generator.Cutting(passPline, CuttingFeed, TechProcess.PenetrationFeed, angleC: angleC, angleA: angleA);

                if (IsOutlet)
                {
                    if (IsA90)
                    {
                        var pt = outletCurve.GetClosestPoint(generator.ToolPosition.Point);
                        generator.Move(pt.X, pt.Y);
                    }
                    else
                    {
                        generator.Uplifting();
                    }
                }
            }
            rail.Dispose();
        }
Esempio n. 10
0
        public void BuildProcessingOld(MillingCommandGenerator generator)
        {
            var sectionProfile = (SectionProfileTechProcess)TechProcess;
            var toolThickness  = TechProcess.Tool.Thickness.Value;

            var rail = sectionProfile.Rail != null?sectionProfile.Rail.GetCurve() as Line : new Line(Point3d.Origin, new Point3d(sectionProfile.Length.Value, 0, 0));

            var railVector  = rail.Delta.GetNormal();
            var passVector  = rail.Delta;
            var crossVector = railVector.RotateBy(-Math.PI / 2, Vector3d.ZAxis);
            var startPass   = rail.StartPoint;
            var shift       = TechProcess.MachineType == MachineType.Donatoni ^ BuilderUtils.CalcEngineSide(rail.Angle) == Side.Left ? toolThickness : 0;

            if (rail.IsNewObject)
            {
                rail.Dispose();
            }

            var profile = sectionProfile.ProcessingArea[0].GetCurve() as Polyline;

            if (profile == null)
            {
                throw new Exception("Профиль должен быть полилинией");
            }

            if (Delta != 0)
            {
                profile = (Polyline)profile.GetOffsetCurves(Delta)[0];
            }

            var endX          = Math.Max(profile.StartPoint.X, profile.EndPoint.X);
            var profilePoints = profile.GetPolylineFitPoints(ProfileStep).Select(p => new Point2d(endX - p.X, p.Y)).ToList();

            if (profilePoints[0].X > Consts.Epsilon)
            {
                profilePoints.Reverse();
            }
            profilePoints = profilePoints
                            .TakeWhile(p => p.X < toolThickness)
                            .Select(p => p - Vector2d.XAxis * toolThickness)
                            .Concat(profilePoints)
                            .ToList();
            var passPoints = profilePoints.Select((p, i) =>
            {
                var y = p.Y;
                for (int j = i + 1; j < profilePoints.Count && profilePoints[j].X - profilePoints[i].X < toolThickness; j++)
                {
                    if (profilePoints[j].Y > y)
                    {
                        y = profilePoints[j].Y;
                    }
                }
                return(new Point2d(p.X, y));
            })
                             .ToList();

            if (Departure > 0)
            {
                passPoints.Insert(0, new Point2d(-Departure, passPoints.First().Y));
                passPoints.Add(new Point2d(passPoints.Last().X + Departure, passPoints.Last().Y));
            }

            var sp = startPass + crossVector * (passPoints[0].X + shift) + passPoints[0].Y * Vector3d.ZAxis;

            generator.Move(sp.X, sp.Y, angleC: BuilderUtils.CalcToolAngle(railVector.GetAngleTo(Vector3d.XAxis)));

            var passPointsDirect = new List <Point2d>[2] {
                passPoints, Enumerable.Reverse(passPoints).ToList()
            };
            int direct = 0;

            Acad.SetLimitProgressor((int)(passVector.Length / LongStep));
            for (double x = 0; x < passVector.Length; x += LongStep)
            {
                Acad.ReportProgressor();
                passPointsDirect[direct].ForEach(p => generator.GCommand(CommandNames.Cutting, 1, point: startPass + crossVector * (p.X + shift) + p.Y * Vector3d.ZAxis + x * railVector, feed: CuttingFeed));
                direct = 1 - direct;
            }
        }
Esempio n. 11
0
        protected override void BuildProcessing(MillingCommandGenerator generator)
        {
            var toolThickness = Tool.Thickness.Value;
            var profile       = ProcessingArea[0].GetCurve();

            if (Delta != 0)
            {
                profile = (Curve)profile.GetOffsetCurves(Delta)[0];
            }

            var zMax = profile.GetStartEndPoints().Max(p => p.Y);

            generator.SetZSafety(ZSafety, zMax);
            var xMax = 0D;

            using (var curve = profile.ToCompositeCurve2d())
                using (var ray = new Ray2d())
                    using (var intersector = new CurveCurveIntersector2d())
                    {
                        var angleC = 360;
                        var gCode  = 2;

                        for (var z = StartZ; z > 0; z -= StepZ)
                        {
                            var xMin = RadiusMin;
                            for (int i = 0; i < 3; i++)
                            {
                                ray.Set(new Point2d(0, z + i * toolThickness / 2), Vector2d.XAxis);
                                intersector.Set(curve, ray);
                                if (intersector.NumberOfIntersectionPoints == 1)
                                {
                                    xMin = Math.Max(xMin, intersector.GetIntersectionPoint(0).X);
                                }
                            }
                            if (xMin == 0)
                            {
                                throw new Exception("Нет точек пересечения с профилем");
                            }

                            var x         = Math.Max(xMin, RadiusMax - Penetration);
                            var s         = x - xMin;
                            int passCount = (int)Math.Ceiling(s / Penetration);
                            var dx        = s > Consts.Epsilon ? s / passCount : 1;

                            if (generator.IsUpperTool)
                            {
                                generator.Move(0, -x - ZSafety, angleC: 0, angleA: 90);
                            }
                            else
                            {
                                generator.Transition(y: -x - ZSafety, feed: CuttingFeed);
                            }
                            generator.Transition(z: z);
                            do
                            {
                                var arc = new Arc(new Point3d(0, 0, z), x, Math.PI * 1.5, Math.PI * 1.5 - Consts.Epsilon);
                                generator.Cutting(0, -x, z, PenetrationFeed);
                                generator.GCommand(CommandNames.Cutting, gCode, angleC: angleC, curve: arc, center: arc.Center.To2d(), feed: CuttingFeed);
                                angleC = 360 - angleC;
                                gCode  = 5 - gCode;
                                x     -= dx;
                            }while (x >= xMin - Consts.Epsilon);

                            xMax = Math.Max(xMin, RadiusMax);
                        }
                        generator.Transition(y: -xMax - ZSafety, feed: PenetrationFeed);
                        generator.Uplifting();
                    }
        }
Esempio n. 12
0
        public override void BuildProcessing(MillingCommandGenerator generator)
        {
            if (PassList?.Any() != true)
            {
                CalcPassList();
            }
            var tactileTechProcess = (TactileTechProcess)TechProcess;
            var thickness          = TechProcess.Tool.Thickness.Value;
            var contour            = tactileTechProcess.GetContour();
            var contourPoints      = contour.GetPolyPoints().ToArray();
            var basePoint          = ProcessingAngle == 45 ? contourPoints[3] : contourPoints[0];
            var ray = new Ray
            {
                BasePoint = basePoint,
                UnitDir   = Vector3d.XAxis.RotateBy(ProcessingAngle.ToRad(), Vector3d.ZAxis)
            };
            var passDir = ray.UnitDir.GetPerpendicularVector();

            if (ProcessingAngle >= 90)
            {
                passDir = passDir.Negate();
            }
            double offset = BandStart - BandSpacing - BandWidth;
            var    size   = (contourPoints[ProcessingAngle == 0 ? 1 : ProcessingAngle == 90 ? 3 : 2] - contourPoints[0]).Length;

            if (IsEdgeProcessing)
            {
                if (ProcessingAngle == 45 ^ TechProcess.MachineType == MachineType.Donatoni)
                {
                    Cutting(0.8 * thickness, CuttingFeed, -thickness);
                }

                if (offset > -0.5 * thickness)
                {
                    var count = offset > 0 ? (int)Math.Ceiling(offset / (0.8 * thickness)) : 1;
                    Algorithms.Range(-0.8 * thickness * count, -0.1, 0.8 * thickness).ForEach(p => Cutting(offset + PassList[0].Pos + p, CuttingFeed));
                }
            }
            do
            {
                foreach (var pass in PassList)
                {
                    Cutting(offset + pass.Pos, pass.CuttingType == CuttingType.Roughing ? CuttingFeed : FeedFinishing);
                }

                offset += BandWidth + BandSpacing;
            }while (offset < size);

            if (IsEdgeProcessing)
            {
                if (offset - BandSpacing < size)
                {
                    Algorithms.Range(offset - BandSpacing, size, 0.8 * thickness).ForEach(p => Cutting(p, CuttingFeed));
                }

                if (ProcessingAngle == 45 ^ TechProcess.MachineType == MachineType.ScemaLogic)
                {
                    Cutting(size - 0.8 * thickness, CuttingFeed, thickness);
                }
            }
            ray.Dispose();
            contour.Dispose();

            void Cutting(double pos, int feed, double s = 0)
            {
                if (pos < 0 || pos > size)
                {
                    return;
                }
                ray.BasePoint = basePoint + passDir * pos;
                var points = new Point3dCollection();

                ray.IntersectWith(contour, Intersect.ExtendThis, new Plane(), points, IntPtr.Zero, IntPtr.Zero);
                if (points.Count == 2)
                {
                    var vector     = (points[1] - points[0]).GetNormal() * tactileTechProcess.Departure;
                    var startPoint = points[0] + passDir * s - vector - Vector3d.ZAxis * Depth;
                    var endPoint   = points[1] + passDir * s + vector - Vector3d.ZAxis * Depth;
                    if (generator.IsUpperTool)
                    {
                        generator.Move(startPoint.X, startPoint.Y, angleC: BuilderUtils.CalcToolAngle(ProcessingAngle.ToRad()));
                    }
                    generator.Cutting(startPoint, endPoint, feed, tactileTechProcess.TransitionFeed);
                }
            }
        }
Esempio n. 13
0
        public override void BuildProcessing(MillingCommandGenerator generator)
        {
            const int CornerIndentIncrease = 5;
            var       curve        = ProcessingArea.GetCurve();
            var       thickness    = TechProcess.Thickness.Value + 2; // запил на 2мм ниже нижнего края
            var       toolDiameter = TechProcess.Tool.Diameter;
            var       engineSide   = Side.None;
            double    offsetArc    = 0;
            double    angleA       = 0;

            if (TechProcess.MachineType == MachineType.ScemaLogic)
            {
                AngleA = 0;
            }

            switch (curve)
            {
            case Arc arc:
                CalcArc(arc);
                break;

            case Line line:
                CalcLine(line);
                break;

            case Polyline polyline:
                CalcPolyline(polyline);
                break;

            default:
                throw new InvalidOperationException($"Кривая типа {curve.GetType()} не может быть обработана.");
            }

            var outerSideSign = OuterSide == Side.Left ^ curve is Line ? -1 : 1;
            var offsetCoeff   = Math.Tan(angleA) * outerSideSign;
            var depthCoeff    = 1 / Math.Cos(angleA);
            var toolThickness = TechProcess.Tool.Thickness.Value * depthCoeff;
            var compensation  = (offsetArc + (engineSide == OuterSide ^ TechProcess.MachineType == MachineType.Donatoni ? toolThickness : 0)) * outerSideSign;
            var shift         = angleA > 0 ? -thickness * offsetCoeff : 0;

            var sumIndent = CalcIndent(thickness) * (Convert.ToInt32(IsExactlyBegin) + Convert.ToInt32(IsExactlyEnd));

            if (sumIndent >= curve.Length())
            {
                if (AngleA != 0)
                {
                    throw new InvalidOperationException("Расчет намечания выполняется только при нулевом вертикальном угле.");
                }
                var point = Scheduling();
                var angle = BuilderUtils.CalcToolAngle((curve.EndPoint - curve.StartPoint).ToVector2d().Angle, engineSide);
                generator.Move(point.X, point.Y, angleC: angle);
                generator.Cutting(point.X, point.Y, point.Z, TechProcess.PenetrationFeed);
                return;
            }

            var modes = SawingModes.ConvertAll(p => new CuttingMode {
                Depth = p.Depth, DepthStep = p.DepthStep, Feed = p.Feed
            });
            var passList = BuilderUtils.GetPassList(modes, thickness, !ProcessingArea.ObjectId.IsLine()).ToList();

            Curve toolpathCurve = null;

            foreach (var item in passList)
            {
                CreateToolpath(item.Key, compensation + shift + item.Key * offsetCoeff);
                if (generator.IsUpperTool)
                {
                    var point  = engineSide == Side.Right ^ (passList.Count() % 2 == 1) ? toolpathCurve.EndPoint : toolpathCurve.StartPoint;
                    var vector = Vector3d.ZAxis * (item.Key + generator.ZSafety);
                    if (angleA != 0)
                    {
                        vector = vector.RotateBy(outerSideSign * angleA, ((Line)toolpathCurve).Delta) * depthCoeff;
                    }
                    var p0     = point + vector;
                    var angleC = BuilderUtils.CalcToolAngle(toolpathCurve, point, engineSide);
                    generator.Move(p0.X, p0.Y, angleC: angleC, angleA: Math.Abs(AngleA));
                    if (TechProcess.MachineType == MachineType.ScemaLogic)
                    {
                        generator.Command("28;;XYCZ;;;;;;", "Цикл");
                    }
                }
                generator.Cutting(toolpathCurve, item.Value, TechProcess.PenetrationFeed, engineSide);
            }
            generator.Uplifting(Vector3d.ZAxis.RotateBy(outerSideSign * angleA, toolpathCurve.EndPoint - toolpathCurve.StartPoint) * (thickness + generator.ZSafety) * depthCoeff);

            if ((!IsExactlyBegin || !IsExactlyEnd) && Departure == 0)
            {
                var gashCurve = curve.GetOffsetCurves(shift)[0] as Curve;
                var gashList  = new List <ObjectId>();
                if (!IsExactlyBegin)
                {
                    gashList.Add(Acad.CreateGash(gashCurve, gashCurve.StartPoint, OuterSide, thickness * depthCoeff, toolDiameter, toolThickness));
                }
                if (!IsExactlyEnd)
                {
                    gashList.Add(Acad.CreateGash(gashCurve, gashCurve.EndPoint, OuterSide, thickness * depthCoeff, toolDiameter, toolThickness));
                }
                if (gashList.Count > 0)
                {
                    Modify.AppendToGroup(base.TechProcess.ExtraObjectsGroup.Value, gashList.ToArray());
                }
                gashCurve.Dispose();
            }

            // Local func ------------------------

            void CalcArc(Arc arc)
            {
                AngleA = 0;
                var startSide      = Math.Sign(Math.Cos(arc.StartAngle.Round(3)));
                var endSide        = Math.Sign(Math.Cos(arc.EndAngle.Round(3)));
                var cornersOneSide = Math.Sign(startSide * endSide);

                if (arc.TotalAngle.Round(3) > Math.PI && cornersOneSide > 0)
                {
                    throw new InvalidOperationException("Обработка дуги невозможна - дуга пересекает углы 90 и 270 градусов.");
                }

                if (cornersOneSide < 0) //  дуга пересекает углы 90 или 270 градусов
                {
                    if (TechProcess.MachineType == MachineType.ScemaLogic)
                    {
                        throw new InvalidOperationException("Обработка дуги невозможна - дуга пересекает угол 90 или 270 градусов.");
                    }

                    engineSide = startSide > 0 ? Side.Left : Side.Right;
                }
                if (OuterSide == Side.Left)                                                         // внутренний рез дуги
                {
                    if (TechProcess.MachineType == MachineType.Donatoni && engineSide != Side.Left) // подворот диска при вн. резе дуги
                    {
                        engineSide = Side.Right;
                        //var comp = arc.Radius - Math.Sqrt(arc.Radius * arc.Radius - thickness * (toolDiameter - thickness));
                        //AngleA = Math.Atan2(comp, thickness).ToDeg();

                        var R    = arc.Radius;
                        var t    = thickness;
                        var d    = toolDiameter;
                        var comp = (2 * R * t * t - Math.Sqrt(-d * d * d * d * t * t + 4 * d * d * R * R * t * t + d * d * t * t * t * t)) / (d * d - 4 * R * R);
                        AngleA = -Math.Atan2(comp, thickness).ToDeg();
                    }
                    else
                    {
                        offsetArc = arc.Radius - Math.Sqrt(arc.Radius * arc.Radius - thickness * (toolDiameter - thickness));
                    }
                }
                if (engineSide == Side.None)
                {
                    engineSide = (startSide + endSide) > 0 ? Side.Right : Side.Left;
                }
            }

            void CalcLine(Line line)
            {
                angleA     = AngleA.ToRad();
                engineSide = AngleA == 0 ? BuilderUtils.CalcEngineSide(line.Angle) : AngleA > 0 ? OuterSide : OuterSide.Opposite();
            }

            void CalcPolyline(Polyline polyline)
            {
                int sign = 0;

                for (int i = 0; i < polyline.NumberOfVertices; i++)
                {
                    var point = polyline.GetPoint3dAt(i);
                    var s     = Math.Sign(Math.Sin(polyline.GetTangent(point).Angle.Round(6)));
                    if (s == 0)
                    {
                        continue;
                    }
                    if (sign == 0)
                    {
                        sign = s;
                        continue;
                    }
                    var bulge = polyline.GetBulgeAt(i - 1);
                    if (bulge == 0)
                    {
                        bulge = polyline.GetBulgeAt(i);
                    }

                    if (s != sign)
                    {
                        if (TechProcess.MachineType == MachineType.ScemaLogic)
                        {
                            throw new InvalidOperationException("Обработка полилинии невозможна - кривая пересекает углы 90 или 270 градусов.");
                        }
                        var side = sign > 0 ^ bulge < 0 ? Side.Left : Side.Right;
                        if (engineSide != Side.None)
                        {
                            if (engineSide != side)
                            {
                                throw new InvalidOperationException("Обработка полилинии невозможна.");
                            }
                        }
                        else
                        {
                            engineSide = side;
                        }
                        sign = s;
                    }
                    else
                    if (Math.Abs(bulge) > 1)
                    {
                        throw new InvalidOperationException("Обработка невозможна - дуга полилинии пересекает углы 90 и 270 градусов.");
                    }
                }
                if (engineSide == Side.None)
                {
                    engineSide = BuilderUtils.CalcEngineSide(polyline.GetTangent(polyline.StartPoint).Angle);
                }
            }

            void CreateToolpath(double depth, double offset)
            {
                toolpathCurve = curve.GetOffsetCurves(offset)[0] as Curve;
                toolpathCurve.TransformBy(Matrix3d.Displacement(-Vector3d.ZAxis * depth));

                if (Departure > 0 && toolpathCurve is Line line)
                {
                    if (!IsExactlyBegin)
                    {
                        toolpathCurve.StartPoint = line.ExpandStart(Departure);
                    }
                    if (!IsExactlyEnd)
                    {
                        toolpathCurve.EndPoint = line.ExpandEnd(Departure);
                    }
                }

                if (!IsExactlyBegin && !IsExactlyEnd)
                {
                    return;
                }
                var indent = CalcIndent(depth * depthCoeff);

                switch (toolpathCurve)
                {
                case Line l:
                    if (IsExactlyBegin)
                    {
                        l.StartPoint = l.GetPointAtDist(indent);
                    }
                    if (IsExactlyEnd)
                    {
                        l.EndPoint = l.GetPointAtDist(l.Length - indent);
                    }
                    break;

                case Arc a:
                    var indentAngle = indent / ((Arc)curve).Radius;
                    if (IsExactlyBegin)
                    {
                        a.StartAngle = a.StartAngle + indentAngle;
                    }
                    if (IsExactlyEnd)
                    {
                        a.EndAngle = a.EndAngle - indentAngle;
                    }
                    break;

                case Polyline p:
                    if (IsExactlyBegin)
                    {
                        p.SetPointAt(0, p.GetPointAtDist(indent).ToPoint2d());
                    }
                    //p.StartPoint = p.GetPointAtDist(indent);
                    if (IsExactlyEnd)
                    {
                        //p.EndPoint = p.GetPointAtDist(p.Length - indent);
                        p.SetPointAt(p.NumberOfVertices - 1, p.GetPointAtDist(p.Length - indent).ToPoint2d());
                    }
                    break;
                }
                ;
            }

            double CalcIndent(double depth) => Math.Sqrt(depth * (toolDiameter - depth)) + CornerIndentIncrease;

            /// <summary>
            /// Расчет точки намечания
            /// </summary>
            Point3d Scheduling()
            {
                var vector = curve.EndPoint - curve.StartPoint;
                var depth  = thickness;
                var point  = Point3d.Origin;

                if (IsExactlyBegin && IsExactlyEnd)
                {
                    var l = vector.Length - 2 * CornerIndentIncrease;
                    depth = (toolDiameter - Math.Sqrt(toolDiameter * toolDiameter - l * l)) / 2;
                    point = curve.StartPoint + vector / 2;
                }
                else
                {
                    var indentVector = vector.GetNormal() * (Math.Sqrt(depth * (toolDiameter - depth)) + CornerIndentIncrease);
                    point = IsExactlyBegin ? curve.StartPoint + indentVector : curve.EndPoint - indentVector;
                    Acad.CreateGash(curve, IsExactlyBegin ? curve.EndPoint : curve.StartPoint, OuterSide, depth, toolDiameter, toolThickness, point);
                }
                return(point + vector.GetPerpendicularVector().GetNormal() * compensation - Vector3d.ZAxis * depth);
            }
        }
Esempio n. 14
0
        protected override void BuildProcessing(MillingCommandGenerator generator)
        {
            //чистка диском под углом А
            return;

            var rail = Rail != null?Rail.GetCurve() as Line : new Line(Point3d.Origin, new Point3d(Length.Value, 0, 0));

            var startRail  = rail.StartPoint;
            var railVector = rail.Delta.GetNormal();

            if (rail.Angle >= Math.PI)
            {
                startRail  = rail.EndPoint;
                railVector = railVector.Negate();
            }
            var startPass  = startRail - railVector * Departure;
            var passVector = railVector * (rail.Length + 2 * Departure);
            var railAngle  = railVector.GetAngleTo(Vector3d.XAxis);

            if (Rail == null)
            {
                rail.Dispose();
            }

            var profile       = ProcessingArea[0].GetCurve();
            var profileLength = profile.Length();

            startPass          = new Point3d(startPass.X, startPass.Y - profile.StartPoint.X, profile.StartPoint.Y);
            generator.ZSafety += profile.StartPoint.Y;

            double dist       = 0;
            var    engineSide = Side.None;
            double angleC;

            do
            {
                var point = profile.GetPointAtDist(dist);

                var distAvg = dist + Tool.Thickness.Value / 2;
                if (distAvg > profileLength)
                {
                    distAvg = profileLength;
                }
                var pointAvg = profile.GetPointAtDist(distAvg);

                var tangent = profile.GetFirstDerivative(pointAvg);
                var angleA  = Math.Abs(tangent.GetAngleTo(Vector3d.XAxis).ToDeg());
                var side    = tangent.Y < 0 ? Side.Left : Side.Right;
                if (engineSide != side)
                {
                    engineSide = side;
                    angleC     = BuilderUtils.CalcToolAngle(railAngle, side);
                    if (!generator.IsUpperTool)
                    {
                        generator.Uplifting();
                    }
                    var sp = GetStartPoint(point, tangent);
                    generator.Move(sp.X, sp.Y, angleC: angleC, angleA: angleA);
                }
                var startPoint = GetStartPoint(point, tangent);
                generator.Cutting(startPoint, startPoint + passVector, CuttingFeed, PenetrationFeed, angleA: angleA);
                dist += Step;
            }while (dist < profileLength);

            generator.Uplifting();

            Point3d GetStartPoint(Point3d point, Vector3d tangent)
            {
                if (engineSide == Side.Left)
                {
                    point += tangent.GetNormal() * Tool.Thickness.Value;
                }
                var profileVector = point - profile.StartPoint;

                return(startPass + railVector.RotateBy(Math.PI / 2, -Vector3d.ZAxis).RotateBy(profileVector.GetAngleTo(Vector3d.XAxis), railVector) * profileVector.Length);
            }
        }
Esempio n. 15
0
        public override void BuildProcessing(MillingCommandGenerator generator)
        {
            var disk3DTechProcess = (Disk3DTechProcess)TechProcess;

            var offsetSurface = CreateOffsetSurface();

            //generator.ZSafety = offsetSurface.GeometricExtents.MinPoint.Z + TechProcess.Thickness.Value + TechProcess.ZSafety;
            //generator.ToolPosition.Point += Vector3d.ZAxis * generator.ZSafety;
            //generator.ToolLocation.Set(new Point3d(double.NaN, double.NaN, generator.ZSafety), 0, TechProcess.IsA90 ? 90 : 0);

            generator.SetZSafety(TechProcess.ZSafety, offsetSurface.GeometricExtents.MinPoint.Z + TechProcess.Thickness.Value);

            Matrix3d?matrix = null;

            if (TechProcess.IsA90)
            {
                matrix = Matrix3d.Rotation(-Math.PI / 2, Vector3d.XAxis, Point3d.Origin);
            }
            if (TechProcess.Angle != 0)
            {
                var m = Matrix3d.Rotation(disk3DTechProcess.Angle.ToRad(), Vector3d.ZAxis, Point3d.Origin);
                matrix = matrix.HasValue ? matrix.Value * m : m;
            }
            if (matrix.HasValue)
            {
                offsetSurface.TransformBy(matrix.Value);
            }
            var bounds = offsetSurface.GeometricExtents;

            //generator.ZSafety = bounds.MinPoint.Z + TechProcess.Thickness.Value + TechProcess.ZSafety;
            //generator.ToolLocation.Point += Vector3d.ZAxis * generator.ZSafety;

            //var ray = new Ray { UnitDir = Vector3d.XAxis };
            //var y = StartPass;
            //do
            //{
            //    ray.BasePoint = new Point3d(0, y, 0);

            //    var curves = s.ProjectOnToSurface(point, Vector3d.ZAxis);
            //    curves[0].ColorIndex = 2;
            //    curves[0].AddToCurrentSpace();
            //    y += StepPass;
            //}
            //while (y < boundsModel.MaxPoint.Y);

            //var startTime = System.Diagnostics.Stopwatch.StartNew();
            //var point = new DBPoint();
            //int cnt = 0;
            //for (var y = boundsModel.MinPoint.Y + StartPass; y < boundsModel.MaxPoint.Y; y += StepPass)
            //{
            //    for (var x = boundsModel.MinPoint.X; x < boundsModel.MaxPoint.X; x += StepLong)
            //    {
            //        for (var s = 0; s <= 2; s += 4)
            //        {
            //            point.Position = new Point3d(x, y + s, 0);

            //            //line.StartPoint = new Point3d(x, y, 0);
            //            //line.EndPoint = new Point3d(x, y + 8, 0);

            //            try
            //            {
            //                var curves = offsetSurfaces.ProjectOnToSurface(point, Vector3d.ZAxis);
            //                cnt++;
            //                if (curves.Length == 0)
            //                    Acad.Write("111");
            //                curves[0].ColorIndex = 6;
            //                curves[0].AddToCurrentSpace();
            //            }
            //            catch
            //            {
            //            }
            //        }
            //    }
            //}
            //startTime.Stop();
            //var resultTime = startTime.Elapsed;
            //Acad.Write("timer=" + resultTime);
            //Acad.Write("cnt=" + cnt);


            //var startTime = System.Diagnostics.Stopwatch.StartNew();
            //var line = new Line();
            //int cnt = 0;
            //int err = 0;
            //for (var y = boundsModel.MinPoint.Y + StartPass; y < boundsModel.MaxPoint.Y; y += StepPass)
            //{
            //    for (var x = boundsModel.MinPoint.X; x < boundsModel.MaxPoint.X; x += StepLong)
            //    {
            //        for (var s = 0; s <= 2; s += 4)
            //        {
            //            line.StartPoint = new Point3d(x, y, 0);
            //            line.EndPoint = new Point3d(x, y + 8, 0);

            //            try
            //            {
            //                var curves = offsetSurfaces.ProjectOnToSurface(line, Vector3d.ZAxis);
            //                cnt++;
            //                if (curves.Length == 0)
            //                    Acad.Write("111");
            //                curves[0].ColorIndex = 6;
            //                curves[0].AddToCurrentSpace();
            //            }
            //            catch (Exception ex)
            //            {
            //                err++;
            //            }
            //        }
            //    }
            //}
            //startTime.Stop();
            //var resultTime = startTime.Elapsed;
            //Acad.Write("timer=" + resultTime);
            //Acad.Write("cnt=" + cnt);

            //var contour = NoDraw.Rectang(new Point3d(bounds.MinPoint.X, bounds.MinPoint.Y, 0), new Point3d(bounds.MaxPoint.X, bounds.MaxPoint.Y, 0));
            //var ray = new Ray
            //{
            //    BasePoint = contour.StartPoint,
            //    UnitDir = Vector3d.XAxis.RotateBy(((Disk3DTechProcess)TechProcess).Angle.ToRad(), Vector3d.ZAxis)
            //};
            //ray.BasePoint += ray.UnitDir.GetPerpendicularVector() * StartPass;
            //var crossVector = ray.UnitDir.GetPerpendicularVector() * StepPass;
            //var plane = new Plane();
            //while (true)
            //{
            //    var pc = new Point3dCollection();
            //    ray.IntersectWith(contour, Intersect.ExtendThis, plane, pc, IntPtr.Zero, IntPtr.Zero);
            //    if (pc.Count != 2)
            //        break;

            //        var vector = (points[1] - points[0]).GetNormal() * tactileTechProcess.TactileTechProcessParams.Departure;
            //        var startPoint = points[0] + passDir * s - vector - Vector3d.ZAxis * Depth;
            //        var endPoint = points[1] + passDir * s + vector - Vector3d.ZAxis * Depth;
            //        if (generator.IsUpperTool)
            //            generator.Move(startPoint.X, startPoint.Y, angleC: BuilderUtils.CalcToolAngle(ProcessingAngle.ToRad()));
            //        generator.Cutting(startPoint, endPoint, feed, tactileTechProcess.TactileTechProcessParams.TransitionFeed);

            //    ray.BasePoint += crossVector;
            //}

            var startY = StartPass == 0 ? bounds.MinPoint.Y : StartPass;
            var endY   = (EndPass == 0 ? bounds.MaxPoint.Y : EndPass) - (disk3DTechProcess.IsExactlyEnd ? TechProcess.Tool.Thickness : 0);

            //double startY, endY;
            //if (!TechProcess.IsA90)
            //{
            //    startY = bounds.MinPoint.Y + StartPass;
            //    var endY = EndPass != 0 ? bounds.MinPoint.Y + EndPass : bounds.MaxPoint.Y;
            //}
            //if (startY < endY)
            //{
            //    if (disk3DTechProcess.IsExactlyEnd)
            //        endY -= TechProcess.Tool.Thickness.Value;
            //}
            //else
            //{
            //    startY -= TechProcess.Tool.Thickness.Value;
            //    if (!disk3DTechProcess.IsExactlyEnd)
            //        endY -= TechProcess.Tool.Thickness.Value;
            //    StepPass *= -1;
            //}

            //var count = bounds.MaxPoint.Y - (disk3DTechProcess.IsExactlyEnd ? TechProcess.Tool.Thickness : 0);
            //Acad.SetLimitProgressor((int)((endY - startY) / StepPass));
            //var PassList = new List<List<Point3d>>();
            //for (var y = startY; StepPass > 0 ? y < endY : y > endY; y += StepPass)



            // расчет точек начала и конца поверхности

            //var boundCurves = new List<Curve>();
            //var entitySet = new DBObjectCollection();
            //offsetSurface.Explode(entitySet);
            //for (int i = 0; i < entitySet.Count; i++)
            //{
            //    if (entitySet[i] is DbSurface)
            //    {
            //        var subEntitySet = new DBObjectCollection();
            //        ((Entity)entitySet[i]).Explode(subEntitySet);
            //        boundCurves.AddRange(subEntitySet.Cast<Curve>());
            //    }
            //    else
            //    {
            //        boundCurves.Add(entitySet[i] as Curve);
            //    }
            //}

            //var boundCurves2d = new List<Curve>();
            //var plene = new Plane(Point3d.Origin, Vector3d.ZAxis);
            //foreach (var curve in boundCurves)
            //{
            //    if (curve != null)
            //    {
            //        boundCurves2d.Add(curve.ToCurve2dArray GetOrthoProjectedCurve(plene));
            //    }
            //}

            Acad.SetLimitProgressor((int)((endY - startY) / StepPass));
            var PassList = new List <List <Point3d> >();

            for (var y = startY; y < endY; y += StepPass)
            {
                Acad.ReportProgressor();
                var points = new Point3dCollection();

                //var pass = new Line2d(new Point2d(bounds.MinPoint.X, y), new Point2d(bounds.MinPoint.X, y));
                //foreach (var cv in boundCurves2d)
                //{
                //    pass.IntersectWith(cv.to);
                //}

                for (var x = bounds.MinPoint.X; x <= bounds.MaxPoint.X; x += StepLong)
                {
                    double z = 0;
                    for (double s = 0; s <= TechProcess.Tool.Thickness; s += TechProcess.Tool.Thickness.Value)
                    {
                        if (y + s > bounds.MaxPoint.Y)
                        {
                            break;
                        }
                        offsetSurface.RayTest(new Point3d(x, y + s, bounds.MinPoint.Z), Vector3d.ZAxis, 0.0001, out SubentityId[] col, out DoubleCollection par);
                        //if (par.Count == 0)
                        //{
                        //    z = 0;
                        //    break;
                        //}
                        if (par.Count > 0)
                        {
                            z = par[par.Count - 1] > z ? par[par.Count - 1] : z;
                        }
                    }
                    if (z > 0)
                    {
                        var point = new Point3d(x, y, bounds.MinPoint.Z + z);
                        var ind   = points.Count - 1;
                        if (ind > 0 && points[ind - 1].GetVectorTo(points[ind]).IsCodirectionalTo(points[ind].GetVectorTo(point)))
                        {
                            points[ind] = point;
                        }
                        else
                        {
                            points.Add(point);
                        }
                        //Draw.Point(point);
                    }
                }
                if (points.Count > 1)
                {
                    PassList.Add(CalcOffsetPoints(points, bounds));
                }
            }
            offsetSurface.Dispose();


            if (matrix.HasValue)
            {
                matrix = matrix.Value.Inverse();
            }
            if (TechProcess.IsA90 && PassList.First()[0].TransformBy(matrix.Value).Z < PassList.Last()[0].TransformBy(matrix.Value).Z)
            {
                PassList.Reverse();
            }
            if (IsReverse)
            {
                PassList.Reverse();
            }

            if (TechProcess.IsA90)
            {
                generator.Matrix = matrix;
            }

            Point3d?lastPoint = null;

            PassList.ForEach(p =>
            {
                var points = p;
                if (TechProcess.MachineType == MachineType.ScemaLogic) //Settongs.IsFrontPlaneZero
                {
                    points = points.ConvertAll(x => new Point3d(x.X, x.Y + TechProcess.Tool.Thickness.Value, x.Z));
                }
                if (matrix.HasValue && !TechProcess.IsA90)
                {
                    points = points.ConvertAll(x => x.TransformBy(matrix.Value));
                }
                var loc = generator.ToolPosition;
                if (lastPoint.HasValue && lastPoint.Value.DistanceTo(points.First()) > lastPoint.Value.DistanceTo(points.Last()))
                {
                    points.Reverse();
                }

                if (TechProcess.IsA90)
                {
                    lastPoint = BuildPassA90(generator, points, matrix.Value, bounds.MinPoint.Z + PenetrationAll);
                }
                else
                {
                    lastPoint = BuildPass(generator, points);
                }
            });
            if (TechProcess.IsA90)
            {
                generator.Move(lastPoint.Value.Add(Vector3d.ZAxis * 100));
            }

            if (generator is DonatoniCommandGenerator donatoniCommandGenerator)
            {
                donatoniCommandGenerator.IsSupressMoveHome = true;
            }
            //progressor.Stop();
        }