找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 772|回复: 2

[每日一码] 实现裁剪功能

[复制链接]

已领礼包: 1个

财富等级: 恭喜发财

发表于 2017-6-3 10:00:04 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
对三维多段线、未拟合的二维多段线还没处理,对园的剪切也不对


[C#] 纯文本查看 复制代码
[CommandMethod("MTRIM")]
        public void m_Trim()
        {
            PromptEntityOptions m_peo = new PromptEntityOptions("\n请选择剪切边");
            m_peo.SetRejectMessage(" It's not a Curve Obecjt!");
            m_peo.AddAllowedClass(typeof(Curve), false);
            PromptEntityResult m_per = m_ed.GetEntity(m_peo);
            if (m_per.Status != PromptStatus.OK) return;

            Point3d m_Pt1 = m_per.PickedPoint;
            Point3d m_Pt2 = new Point3d();
            if (!mFun.m_GetPoint("\n剪切方向", ref m_Pt2, m_Pt1, false, false)) return;

            ObjectIdCollection m_OldObjIds = new ObjectIdCollection();//保存被剪前的实体ID
            List m_NewEntArr = new List();

            Entity m_OffsetEnt = null;//保存偏移实体
            Point3dCollection m_JdPts = new Point3dCollection();//保存交点坐标
            ObjectIdCollection m_DelObjIds = new ObjectIdCollection();//保存裁剪后的需要删除实体

            using (Transaction m_tr = m_db.TransactionManager.StartTransaction())
            {
                Curve m_TrimEdgeEnt = (Curve)m_tr.GetObject(m_per.ObjectId, OpenMode.ForRead);//剪切边界实体
                m_Pt1 = m_TrimEdgeEnt.GetClosestPointTo(m_Pt2, false);//曲线外一点距曲线最近的点
                Vector3d m_Vect = m_TrimEdgeEnt.GetFirstDerivative(m_Pt1);//曲线上此点的切向量
                double m_dOffset = 0.0001;//偏移量
                if (mFun.m_PtSide(m_Pt1, m_Pt1.Add(m_Vect), m_Pt2) < 0) m_dOffset = -m_dOffset;
                DBObjectCollection m_Objs = m_TrimEdgeEnt.GetOffsetCurves(m_dOffset);
                foreach (DBObject obj in m_Objs) ;
                Curve m_TrimEdgeEntOffset = (Curve)m_Objs[0];//得到剪切边偏移后的实体

                m_OffsetEnt =(Curve) m_TrimEdgeEnt.Clone();

                PromptSelectionResult m_psr = m_ed.SelectCrossingWindow(m_TrimEdgeEnt.GeomExtents.MinPoint, m_TrimEdgeEnt.GeomExtents.MaxPoint);//选择与剪切边包围的所有实体
                foreach (ObjectId objid in m_psr.Value.GetObjectIds())
                {
                    if (!objid.Equals(m_per.ObjectId))
                    {
                        Entity m_Ent = (Entity)m_tr.GetObject(objid, OpenMode.ForWrite);
                        //m_ed.WriteMessage("\nObject={0}", m_Ent.GetType().ToString());
                        if (m_Ent is Curve)//判断是否是曲线类实体
                        {
                            Curve m_Cur = (Curve)m_Ent;

                            Point3dCollection m_InterPts = m_GetInterPoints(m_Cur, m_TrimEdgeEnt);//求被剪曲线与剪切边的交点
                            if (m_InterPts.Count > 0)//判断曲线是否与剪切边相交
                            {
                                foreach (Point3d pt in m_InterPts) m_JdPts.Add(pt);

                                m_OldObjIds.Add(objid);//先保存这个曲线实体
                                m_ed.WriteMessage("");
                                try
                                {
                                    m_Objs = m_Cur.GetSplitCurves(m_InterPts);//拆分曲线实体
                                    foreach (Curve cur in m_Objs)
                                    {
                                        m_InterPts = m_GetInterPoints(cur, m_TrimEdgeEntOffset);
                                        if (m_InterPts.Count == 0)//判断个实体是否与剪切边线的偏移线有交点
                                            m_NewEntArr.Add(cur);
                                    }
                                    m_DelObjIds.Add(objid);
                                }
                                catch(System.Exception e)
                                {
                                    m_ed.WriteMessage(" 错误:{0}", e.Message);
                                }

                            }
                        }
                    }
                  
                }
                m_tr.Commit();
            }

            foreach (Entity ent in m_NewEntArr) mDraw.m_CreateEntity(ent);//生成实体(加入图形数据库)
            foreach (ObjectId ObjId in m_DelObjIds) mDraw.m_EraseEntity(ObjId);//从数据库中删除实体
        }


另外一个代码,使用TRIM命令

[C#] 纯文本查看 复制代码
private void TrimMap(Polyline cutBox)
        {
            //关闭对象捕捉功能避免误删除
            Application.SetSystemVariable("SNAPMODE",0);
            Application.SetSystemVariable("MODEMACRO", "正在修剪...");
            //获取最小与最大点
            Point3d minPoint = cutBox.GeometricExtents.MinPoint;
            Point3d maxPoint = cutBox.GeometricExtents.MaxPoint;
            //设置缩放视口
            CommandLine.Command("Zoom", "W", new Point3d(minPoint.X - 10, minPoint.Y - 10, 0), new Point3d(maxPoint.X + 10, maxPoint.Y + 10, 0));
            //裁剪精度
            Polyline offsetBox = cutBox.GetOffsetCurves(0.2)[0] as Polyline;
            if (offsetBox.Area < cutBox.Area)
            {
                offsetBox = cutBox.GetOffsetCurves(-0.2)[0] as Polyline;
            }
            //裁剪
            for (int i = 0; i < offsetBox.NumberOfVertices;i++ )
            {
                Point3d p1 = offsetBox.GetPoint3dAt(i);
                Point3d p2 = new Point3d();
                if (i == offsetBox.NumberOfVertices-1)
                {
                    p2 = offsetBox.GetPoint3dAt(0);
                }
                else
                {
                    p2 = offsetBox.GetPoint3dAt(i + 1);
                }
                CommandLine.Command("TRIM", cutBox.ObjectId, "", "F", p1, p2, "", "");
            }
            offsetBox.Dispose();
            Application.SetSystemVariable("MODEMACRO", "修剪完成...");
        }


另外一个代码,,参考

[C#] 纯文本查看 复制代码
//改造成c#版本,不过offsetBox会引起错误,不知道怎么解决       
public void TRimByCommandLine()
        {
            //关闭对象捕捉功能避免误删除
            Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("SNAPMODE", 0);
            
            Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("MODEMACRO", "正在修剪...");
            Polyline cutBox;
            Autodesk.AutoCAD.DatabaseServices.Database db = Autodesk.AutoCAD.DatabaseServices.HostApplicationServices.WorkingDatabase;
            PromptEntityResult per = ed.GetEntity("选择边线"); 
            if (per.Status != PromptStatus.OK) return;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                cutBox = (Polyline)tr.GetObject(per.ObjectId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead);//剪切边界实体
                tr.Dispose();
            }
             
            //获取最小与最大点
            Point3d minPoint = cutBox.GeometricExtents.MinPoint;
            Point3d maxPoint = cutBox.GeometricExtents.MaxPoint;
            //设置缩放视口
            acdDoc.SendCommand("Zoom\rW\r");
            acdDoc.SendCommand((minPoint.X - 10).ToString() + "," + (minPoint.Y - 10).ToString() + "\r");
            acdDoc.SendCommand((maxPoint.X + 10).ToString() + "," + (maxPoint.Y + 10).ToString() + "\r");
            //裁剪精度
            Polyline offsetBox = cutBox.GetOffsetCurves(0.2)[0] as Polyline;
            if (offsetBox.Area < cutBox.Area)
            {
                offsetBox = cutBox.GetOffsetCurves(-0.2)[0] as Polyline;
            }
            Point3d[] p = new Point3d[offsetBox.NumberOfVertices];
            for (int i = 0; i < offsetBox.NumberOfVertices; i++)
            {
                p[i]=new Point3d(offsetBox.GetPoint3dAt(i).X, offsetBox.GetPoint3dAt(i).Y, 0);
            }
            //裁剪
            acdDoc.SendCommand("TRIM\r");
            acdDoc.SendCommand(cutBox.ObjectId.ToString() + "\r\r");
            for (int i = p.GetLowerBound(0); i <= p.GetUpperBound(0); i++)
            {
                Point3d p1 = p[i];
                Point3d p2 = new Point3d();
                if (i == p.GetUpperBound(0))
                {
                    p2 = p[0];
                }
                else
                {
                    p2 = p[i + 1];
                }
                acdDoc.SendCommand("f\r");
                acdDoc.SendCommand(p1.X.ToString()+","+p1.Y.ToString() + "\r");
                acdDoc.SendCommand(p2.X.ToString()+","+p2.Y.ToString() + "\r\r");
             }
            acdDoc.SendCommand("\r");
            Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("MODEMACRO", "修剪完成...");
        }
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 70个

财富等级: 招财进宝

发表于 2017-6-4 16:24:34 | 显示全部楼层
看来裁剪还是挺复杂的。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2017-6-20 16:20:40 | 显示全部楼层
恩恩,不错,学习了,谢谢分享
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-4-18 14:07 , Processed in 0.393131 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表