打断并删除裁剪框外的线

 

using IfoxDemo;
namespace IFoxDemo;

public class Class1
{
    [CommandMethod("xx")]

    public static void Demo()
    {
        //"ifox可以了".Print();
        using var tr = new DBTrans();//开事务
        Database db = HostApplicationServices.WorkingDatabase;
        Editor ed = Env.Editor;
        var doc = Env.Document;
        "请选择全部需裁剪对象:\n".Print();
        var psr = ed.GetSelection();//提示框选待裁剪图元
        if (psr.Status != PromptStatus.OK) return;
        var pcat = ed.GetEntity("请选择裁剪框:");//提示选裁剪框
        if (pcat.Status != PromptStatus.OK ) return;
        var ppr = ed.GetPoint("请选择需删除的边界一侧点");//提示选点
        if (ppr.Status != PromptStatus.OK ) return;
        var p0 = ppr.Value;//获取点坐标
        var catobj = pcat.ObjectId.GetObject();//获取裁剪框对象
        Curve cat = null;//定义裁剪框曲线
        if (catobj is Curve)
        {
            cat = catobj as Curve;
        }
        if (cat == null) return;
        List<Curve> curs = new List<Curve>();//创建list待裁剪曲线对象
        foreach (var id in psr.Value.GetObjectIds())//遍历待裁剪图元id
        {
            var obj = id.GetObject();//根据id获取对象
            if (obj is Curve cur)
            {
                curs.Add(cur);//对象加入曲线列表
            }
        }
        if (curs.Contains(cat)) curs.Remove(cat);//如果曲线列表包含裁剪框,那么移除裁剪框
        if(curs.Count > 0)//如果曲线类型的待裁剪图元不为空,执行以下操作
        {
            var sps = 自动修剪(curs,cat, p0);//根据三个参数,修剪曲线,返回另一侧曲线列表
            foreach (var c in sps)//遍历修剪后的另一侧曲线
            {
                if (c.IsNewObject) //如果曲线被修剪生成了新对象,那么把新对象加入当前空间
                { 
                    tr.CurrentSpace.AddEntity(c);
                }
                else
                {
                    curs.Remove(c);//如果曲线未被修剪,那么从原始曲线列表中移除此对象
                }
            }
            foreach (var item in curs)//再次遍历删除原始曲线对象(另一侧未被修剪的不用删除)
            {
                db.Erase(item);//李小科版删除模型空间中实体,需要using
               // tr.BlockTable.Remove(item.ObjectId);//删除修剪前的曲线对象,未能删除,待完善。
            }
        }
    }
    public static List<Curve> 自动修剪(List<Curve>curs,Curve cat,Point3d ptseed)//返回另一侧曲线列表
    {
        List<Curve> lingyice = new List<Curve>();
        var zuijindian0=cat.GetClosestPointTo(ptseed,false);//获取图框上与指定点距离最近的一个点
        var vt10 = zuijindian0.GetVectorTo(ptseed);//图框点到指定点的向量
        var vt20 = cat.GetFirstDerivative(zuijindian0);//图框上一点的切线向量
        var vt30= vt10.CrossProduct(vt20);//图框点到指定点的向量 叉乘 图框点的切线向量,
        foreach (var cur in curs)//遍历待裁剪曲线对象
        {
            var ptc = new Point3dCollection();//新建点集合
            cat.IntersectWith(cur,Intersect.OnBothOperands,ptc,IntPtr.Zero ,IntPtr.Zero );//图框与待裁剪曲线相交,返回相交点集合
            if (ptc.Count ==0)//如果不想交 
            {
                neiwai(cur);//判断曲线并加入另一侧曲线
            }
            else//如果相交
            {
                var pts = new List<Point3d>();//新建点列表
                foreach (Point3d item in ptc)
                {
                    pts.Add(item);//点集合加入点列表
                }
                var vv = from p in pts orderby cur.GetParameterAtPoint(cur.GetClosestPointTo(p,false))select p;//曲线上到点列表的最近点,然后排序
                ptc = new Point3dCollection(vv.ToArray());//曲线上的交点排序
                var fenjies = cur.GetSplitCurves(ptc);//曲线根据排序后的交点分解曲线
                foreach (Curve item in fenjies)
                {
                    neiwai(item);//分解后的曲线,执行内部函数。当程序比较繁琐时,可采用内部函数的方法,简化主函数。
                }
            }
        }
        void neiwai(Curve cur)//内部方法,返回选点的另一侧曲线
        {
            var zhongdian = cur.GetPointAtParameter(cur.StartParam / 2 + cur.EndParam / 2);//待裁剪曲线,(起始点参数+终点参数)/2,即中点的参数,求出中点的坐标
            var zuijindian = cat.GetClosestPointTo(zhongdian,false);//图框上到曲线中点的最近点
            var vt1 = zuijindian.GetVectorTo(zhongdian);//图框上的点到曲线中点的向量
            var vt2 = cat.GetFirstDerivative(zuijindian);//图框上点的切线向量
            var vt3 = vt1.CrossProduct(vt2);//图框上的点到曲线中点的向量 叉乘 图框上点的切线向量
            var tong = vt3.Z*vt30.Z>0; //叉乘大于0
            if (!tong)
            {
                lingyice.Add(cur);//如果小于0,在选点的另一侧,加入另一侧曲线
            }
        }
        return lingyice;//
    }
}

封装erase

 public static void Erase(this Database db, Entity entity)
 {
     // Database db = HostApplicationServices.WorkingDatabase;
     using (Transaction trans = db.TransactionManager.StartTransaction())
     {
         if (entity == null)
         {
             return;
         }
         if (entity.IsNewObject) return;
         //if (!entity.IsErased) 
         //{
         entity.ObjectId.GetObject(OpenMode.ForWrite);
         entity.Erase();
         trans.Commit();
         // }
     }
 }
 public static void Erase<T>(this Database db, List<T> entities) where T : Entity
 {
     // Database db = HostApplicationServices.WorkingDatabase;
     foreach (var entity in entities)
     {
         using (Transaction trans = db.TransactionManager.StartTransaction())
         {
             if (entity == null)
             {
                 return;
             }
             if (entity.IsNewObject) return;
             //if (!entity.IsErased) 
             //{
             entity.ObjectId.GetObject(OpenMode.ForWrite);
             entity.Erase();
             trans.Commit();
             // }
         }

     }
 }

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山水CAD插件定制

你的鼓励是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值