NX二次开发 使用直线和圆弧对样条曲线进行拟合

可以采用生成刀轨的方式,按照样条曲线的轨迹生成刀路,将其输出为后处理文件后,再进行解析。

using System;
using NXOpen;
using NXOpenUI;
using NXOpen.Utilities;
using NXOpen.UF;
using FxpApi;
using NXOpen.BlockStyler;
using NXOpen.CAM;
using System.IO;
using System.Collections.Generic;
using System.Threading;

//------------------------------------------------------------------------------
//Represents Block Styler application class
//------------------------------------------------------------------------------
public class FitCurves
{
    //class members
    public static Session theSession = null;
    public static UI theUI = null;
    public static UFSession theUFSession = null;
    public static Part workPart = null;


    private string theDlxFileName;
    private NXOpen.BlockStyler.BlockDialog theDialog;
    private NXOpen.BlockStyler.SelectObject selection0;// Block type: Selection
    //------------------------------------------------------------------------------
    //Bit Option for Property: SnapPointTypesEnabled
    //------------------------------------------------------------------------------
    public static readonly int SnapPointTypesEnabled_UserDefined = (1 << 0);
    public static readonly int SnapPointTypesEnabled_Inferred = (1 << 1);
    public static readonly int SnapPointTypesEnabled_ScreenPosition = (1 << 2);
    public static readonly int SnapPointTypesEnabled_EndPoint = (1 << 3);
    public static readonly int SnapPointTypesEnabled_MidPoint = (1 << 4);
    public static readonly int SnapPointTypesEnabled_ControlPoint = (1 << 5);
    public static readonly int SnapPointTypesEnabled_Intersection = (1 << 6);
    public static readonly int SnapPointTypesEnabled_ArcCenter = (1 << 7);
    public static readonly int SnapPointTypesEnabled_QuadrantPoint = (1 << 8);
    public static readonly int SnapPointTypesEnabled_ExistingPoint = (1 << 9);
    public static readonly int SnapPointTypesEnabled_PointonCurve = (1 << 10);
    public static readonly int SnapPointTypesEnabled_PointonSurface = (1 << 11);
    public static readonly int SnapPointTypesEnabled_PointConstructor = (1 << 12);
    public static readonly int SnapPointTypesEnabled_TwocurveIntersection = (1 << 13);
    public static readonly int SnapPointTypesEnabled_TangentPoint = (1 << 14);
    public static readonly int SnapPointTypesEnabled_Poles = (1 << 15);
    public static readonly int SnapPointTypesEnabled_BoundedGridPoint = (1 << 16);
    public static readonly int SnapPointTypesEnabled_FacetVertexPoint = (1 << 17);
    //------------------------------------------------------------------------------
    //Bit Option for Property: SnapPointTypesOnByDefault
    //------------------------------------------------------------------------------
    public static readonly int SnapPointTypesOnByDefault_EndPoint = (1 << 3);
    public static readonly int SnapPointTypesOnByDefault_MidPoint = (1 << 4);
    public static readonly int SnapPointTypesOnByDefault_ControlPoint = (1 << 5);
    public static readonly int SnapPointTypesOnByDefault_Intersection = (1 << 6);
    public static readonly int SnapPointTypesOnByDefault_ArcCenter = (1 << 7);
    public static readonly int SnapPointTypesOnByDefault_QuadrantPoint = (1 << 8);
    public static readonly int SnapPointTypesOnByDefault_ExistingPoint = (1 << 9);
    public static readonly int SnapPointTypesOnByDefault_PointonCurve = (1 << 10);
    public static readonly int SnapPointTypesOnByDefault_PointonSurface = (1 << 11);
    public static readonly int SnapPointTypesOnByDefault_PointConstructor = (1 << 12);
    public static readonly int SnapPointTypesOnByDefault_BoundedGridPoint = (1 << 16);

    //------------------------------------------------------------------------------
    //Constructor for NX Styler class
    //------------------------------------------------------------------------------
    public FitCurves()
    {
        try
        {
            theSession = Session.GetSession();
            theUI = UI.GetUI();
            theUFSession = UFSession.GetUFSession();
            workPart = theSession.Parts.Work;

            theDlxFileName = "FitCurves.dlx";
            theDialog = theUI.CreateDialog(theDlxFileName);
            theDialog.AddApplyHandler(new NXOpen.BlockStyler.BlockDialog.Apply(apply_cb));
            theDialog.AddOkHandler(new NXOpen.BlockStyler.BlockDialog.Ok(ok_cb));
            theDialog.AddUpdateHandler(new NXOpen.BlockStyler.BlockDialog.Update(update_cb));
            theDialog.AddCancelHandler(new NXOpen.BlockStyler.BlockDialog.Cancel(cancel_cb));
            theDialog.AddFilterHandler(new NXOpen.BlockStyler.BlockDialog.Filter(filter_cb));
            theDialog.AddInitializeHandler(new NXOpen.BlockStyler.BlockDialog.Initialize(initialize_cb));
            theDialog.AddDialogShownHandler(new NXOpen.BlockStyler.BlockDialog.DialogShown(dialogShown_cb));
        }
        catch (Exception ex)
        {
            //---- Enter your exception handling code here -----
            throw ex;
        }
    }

    public static void Main()
    {
        FitCurves theFitCurves = null;
        try
        {
            theFitCurves = new FitCurves();
            // The following method shows the dialog immediately
            theFitCurves.Show();
        }
        catch (Exception ex)
        {
            //---- Enter your exception handling code here -----
            theUI.NXMessageBox.Show("Block Styler", NXMessageBox.DialogType.Error, ex.ToString());
        }
        finally
        {
            if (theFitCurves != null)
                theFitCurves.Dispose();
            theFitCurves = null;
        }
    }

    public static int GetUnloadOption(string arg)
    {
        //return System.Convert.ToInt32(Session.LibraryUnloadOption.Explicitly);
        return System.Convert.ToInt32(Session.LibraryUnloadOption.Immediately);
        // return System.Convert.ToInt32(Session.LibraryUnloadOption.AtTermination);
    }


    public static void UnloadLibrary(string arg)
    {
        try
        {
            //---- Enter your code here -----
        }
        catch (Exception ex)
        {
            //---- Enter your exception handling code here -----
            theUI.NXMessageBox.Show("Block Styler", NXMessageBox.DialogType.Error, ex.ToString());
        }
    }


    public NXOpen.UIStyler.DialogResponse Show()
    {
        try
        {
            theDialog.Show();
        }
        catch (Exception ex)
        {
            //---- Enter your exception handling code here -----
            theUI.NXMessageBox.Show("Block Styler", NXMessageBox.DialogType.Error, ex.ToString());
        }
        return 0;
    }


    public void Dispose()
    {
        if (theDialog != null)
        {
            theDialog.Dispose();
            theDialog = null;
        }
    }


    public void initialize_cb()
    {
        try
        {
            selection0 = (NXOpen.BlockStyler.SelectObject)theDialog.TopBlock.FindBlock("selection0");
        }
        catch (Exception ex)
        {
            //---- Enter your exception handling code here -----
            theUI.NXMessageBox.Show("Block Styler", NXMessageBox.DialogType.Error, ex.ToString());
        }
    }


    public void dialogShown_cb()
    {
        try
        {
            //---- Enter your callback code here -----
        }
        catch (Exception ex)
        {
            //---- Enter your exception handling code here -----
            theUI.NXMessageBox.Show("Block Styler", NXMessageBox.DialogType.Error, ex.ToString());
        }
    }


    public int apply_cb()
    {
        int errorCode = 0;
        try
        {
            Run_Main();
        }
        catch (Exception ex)
        {
            //---- Enter your exception handling code here -----
            errorCode = 1;
            theUI.NXMessageBox.Show("Block Styler", NXMessageBox.DialogType.Error, ex.ToString());
        }
        return errorCode;
    }


    public int update_cb(NXOpen.BlockStyler.UIBlock block)
    {
        try
        {
            if (block == selection0)
            {
                //---------Enter your code here-----------
            }
        }
        catch (Exception ex)
        {
            //---- Enter your exception handling code here -----
            theUI.NXMessageBox.Show("Block Styler", NXMessageBox.DialogType.Error, ex.ToString());
        }
        return 0;
    }


    public int ok_cb()
    {
        int errorCode = 0;
        try
        {
            errorCode = apply_cb();

        }
        catch (Exception ex)
        {
            //---- Enter your exception handling code here -----
            errorCode = 1;
            theUI.NXMessageBox.Show("Block Styler", NXMessageBox.DialogType.Error, ex.ToString());
        }
        return errorCode;
    }


    public int cancel_cb()
    {
        try
        {
            //---- Enter your callback code here -----
        }
        catch (Exception ex)
        {
            //---- Enter your exception handling code here -----
            theUI.NXMessageBox.Show("Block Styler", NXMessageBox.DialogType.Error, ex.ToString());
        }
        return 0;
    }


    public int filter_cb(NXOpen.BlockStyler.UIBlock block, NXOpen.TaggedObject selectedObject)
    {
        return (NXOpen.UF.UFConstants.UF_UI_SEL_ACCEPT);
    }


    public PropertyList GetBlockProperties(string blockID)
    {
        PropertyList plist = null;
        try
        {
            plist = theDialog.GetBlockProperties(blockID);
        }
        catch (Exception ex)
        {
            //---- Enter your exception handling code here -----
            theUI.NXMessageBox.Show("Block Styler", NXMessageBox.DialogType.Error, ex.ToString());
        }
        return plist;
    }


    
    public void Run_Main()
    {
        var selObjs = selection0.GetSelectedObjects();
        if (selObjs.Length != 1)
        {
            NxOpen.MsgNx("请先择正确的对象!");
            return;
        }
        
        //将控件对象转化为Spline对象
        Spline spline = selObjs[0] as Spline;

        //创建操作
        Operation op = workPart.CAMSetup.CAMOperationCollection.Create(
            NxOpen.CreateNcGroup("NC_PROGRAM"),
            NxOpen.CreateMethod("DefaultMethod_Fxp"),
            NxOpen.CreateTool("TEST10", 10, 0),
            NxOpen.CreateMCS("MCS"),
            "mill_planar",
            "PLANAR_MILL",
             NXOpen.CAM.OperationCollection.UseDefaultName.True, "123");

        //设置操作的底面
        var pmb = NxOpen.SetPlanarMillFloorPlane(op, 0);

        
        Plane plane_zero = NxOpen.CreatePlanar(0);
        //设置操作的边界几何体
        NxOpen.SetCurvesToPlaneMill(op.Tag, plane_zero.Tag, new Tag[] { spline.Tag },
             CamGeomType.CamPart,//部件边界
             CamBoundaryType.CamBoundaryTypeOpen,//开放区域
             CamMaterialSide.CamMaterialSideInLeft,//左侧
             CamToolPosition.CamToolPositionOn);  //对中

        //刀轨参数:轮廓加工模式
        pmb.CutPattern.CutPattern = CutPatternBuilder.Types.Profile;

        //刀轨参数:移除刀轨的进退刀类型。
        pmb.NonCuttingBuilder.EngageClosedAreaBuilder.EngRetType = NcmPlanarEngRetBuilder.EngRetTypes.None;
        pmb.NonCuttingBuilder.EngageOpenAreaBuilder.EngRetType = NcmPlanarEngRetBuilder.EngRetTypes.None;
        pmb.NonCuttingBuilder.RetractAreaBuilder.EngRetType = NcmPlanarEngRetBuilder.EngRetTypes.None;

        pmb.Commit();
        //生成刀轨
        op.GenToolPath();
        workPart.Views.UpdateDisplay();

        //输出后处理文件
        workPart.CAMSetup.Postprocess(new CAMObject[] { op }, "Fxp_Post_FitCurves",
            Base.GetFileLocal() + "test.txt", CAMSetup.OutputUnits.Metric);

        List<PostLinePropry> allPls = new List<PostLinePropry>();

        //读取后处理文件的所有行
        string[] allLines = File.ReadAllLines(Base.GetFileLocal() + "test.txt");
        bool IsStart = false;
        //遍历文件、解析数据
        foreach (string line in allLines)
        {
            if (line.Contains("X") && line.Contains("Y"))
                IsStart = true;
            if (!IsStart)
                continue;
            if (!line.Contains("X") && !line.Contains("Y") && !line.Contains("Z") && !line.Contains("I") && !line.Contains("J"))
                break;
            PostLinePropry pl = new PostLinePropry();
            foreach (string subRange in line.Split(' '))
            {
                if (subRange.Contains("X"))
                    pl.X = Convert.ToDouble(subRange.Split('X')[1]);
                if (subRange.Contains("Y"))
                    pl.Y = Convert.ToDouble(subRange.Split('Y')[1]);
                if (subRange.Contains("Z"))
                    pl.Z = Convert.ToDouble(subRange.Split('Z')[1]);
                if (subRange.Contains("I"))
                    pl.I = Convert.ToDouble(subRange.Split('I')[1]);
                if (subRange.Contains("J"))
                    pl.J = Convert.ToDouble(subRange.Split('J')[1]);
                if (subRange.Contains("K"))
                    pl.K = Convert.ToDouble(subRange.Split('K')[1]);
                if (subRange.Contains("G"))
                {
                    int type = Convert.ToInt32(subRange.Split('G')[1]);
                    if (type == 1)
                        pl.MoveMode = PostLinePropry.MoveModeEnum.Move_Line;
                    if (type == 2)
                        pl.MoveMode = PostLinePropry.MoveModeEnum.Move_Arc_G2;
                    if (type == 3)
                        pl.MoveMode = PostLinePropry.MoveModeEnum.Move_Arc_G3;
                }
            }
            if (allPls.Count == 0)
                pl.MoveMode = PostLinePropry.MoveModeEnum.Move_Start;
            if (pl.X == 0 && pl.Y == 0 && pl.I == 0 && pl.J == 0)
                continue;
            allPls.Add(pl);
        }

        //遍历数据,并创建圆和直线对样条拟合
        FxpApiOther o = new FxpApiOther();
        for (int i = 0; i < allPls.Count; i++)
        {
            Thread.Sleep(200);
            workPart.Views.UpdateDisplay();

            PostLinePropry pl = allPls[i];
            PostLinePropry _pl = null;
            if (i != 0)
                _pl = allPls[i - 1];
            if (pl.MoveMode == PostLinePropry.MoveModeEnum.Move_Start)
            {
                o.CreatePoint(new double[] { pl.X, pl.Y, pl.Z });
                continue;
            }
            if (pl.MoveMode == PostLinePropry.MoveModeEnum.SameAsBack)
            {
                pl.MoveMode = _pl.MoveMode;
            }
            if (pl.MoveMode == PostLinePropry.MoveModeEnum.Move_Line)
            {
                o.CreateLine(new double[] { _pl.X, _pl.Y, _pl.Z }, new double[] { pl.X, pl.Y, pl.Z });
            }
            if (pl.MoveMode == PostLinePropry.MoveModeEnum.Move_Arc_G2)
            {
                Tag oTag = o.CreatePoint(new double[] { pl.X, pl.Y, pl.Z });
                theUFSession.Obj.SetColor(oTag, 186);
                Tag cTag = o.CreateArc(new double[] { _pl.X + pl.I, _pl.Y + pl.J, _pl.Z + pl.K }, GetRaduis(_pl.X, _pl.Y, _pl.Z, _pl.X + pl.I, _pl.Y + pl.J, _pl.Z + pl.K));
                theUFSession.Obj.SetColor(cTag, 186);
            }
            if (pl.MoveMode == PostLinePropry.MoveModeEnum.Move_Arc_G3)
            {
                Tag oTag = o.CreatePoint(new double[] { pl.X, pl.Y, pl.Z });
                theUFSession.Obj.SetColor(oTag, 36);
                Tag cTag = o.CreateArc(new double[] { _pl.X + pl.I, _pl.Y + pl.J, _pl.Z + pl.K }, GetRaduis(_pl.X, _pl.Y, _pl.Z, _pl.X + pl.I, _pl.Y + pl.J, _pl.Z + pl.K));
                theUFSession.Obj.SetColor(cTag, 36);
            }
        }
    }

    /// <summary>
    /// 获取半径值:即圆心位置到圆弧起始位置的距离
    /// </summary>
    /// <param name="X"></param>
    /// <param name="Y"></param>
    /// <param name="Z"></param>
    /// <param name="I"></param>
    /// <param name="J"></param>
    /// <param name="K"></param>
    /// <returns></returns>
    public double GetRaduis(double X, double Y, double Z, double I, double J, double K)
    {
        return Math.Sqrt(Math.Pow(X - I, 2) + Math.Pow(Y - J, 2) + Math.Pow(Z - K, 2));
    }

    /// <summary>
    /// 数据类
    /// </summary>
    public class PostLinePropry
    {
        public PostLinePropry()
        {
            //默认的构造函数给枚举设置为与上一个相同
            MoveMode = MoveModeEnum.SameAsBack;
        }

        /// <summary>
        /// 刀轨运动模式枚举
        /// </summary>
        public enum MoveModeEnum
        {
            /// <summary>
            /// 刀轨开始
            /// </summary>
            Move_Start = 0,

            /// <summary>
            /// 刀轨运动模式与上一个相同
            /// </summary>
            SameAsBack = 1,

            /// <summary>
            /// 直线运动模式(G01)
            /// </summary>
            Move_Line = 2,

            /// <summary>
            /// 圆弧运动模式(G02)
            /// </summary>
            Move_Arc_G2 = 3,

            /// <summary>
            /// 圆弧运动模式(G03)
            /// </summary>
            Move_Arc_G3 = 4
        }

        /// <summary>
        /// X坐标(圆弧起始位置)
        /// </summary>
        public double X { get; set; }

        /// <summary>
        /// Y坐标(圆弧起始位置)
        /// </summary>
        public double Y { get; set; }

        /// <summary>
        /// Y坐标(圆弧起始位置)
        /// </summary>
        public double Z { get; set; }

        /// <summary>
        /// I值(圆弧起始位置距离圆弧中心的X方向投影距离)
        /// </summary>
        public double I { get; set; }

        /// <summary>
        /// J值(圆弧起始位置距离圆弧中心的Y方向投影距离)
        /// </summary>
        public double J { get; set; }

        /// <summary>
        /// K值(圆弧起始位置距离圆弧中心的Z方向投影距离)
        /// </summary>
        public double K { get; set; }

        /// <summary>
        /// 刀轨运动模式
        /// </summary>
        public MoveModeEnum MoveMode { get; set; }
    }

}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值