雪山飞狐_lzh 发表于 2009-6-19 17:39:00

<p>要多调试下:),椭圆的转换有点问题</p><p>效率暂时不考虑</p>

雪山飞狐_lzh 发表于 2009-6-20 07:50:00

本帖最后由 作者 于 2009-6-23 21:11:20 编辑

发现问题在GetParamFromGeCurve方法
Ge的param和DB的param完全不是一回事
要把GeCurve打断再转换为DBCurve应该没问题
贴一个老外的DBCurve转GeCurve类,不完整:)
http://www.theswamp.org/index.php?topic=29217.0
using System;
using System.Collections.Generic;
using System.Text;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
namespace GeometricConversion
{
    class EntityToGeom
    {
      //Fields
      private CompositeCurve3d m_compCurve;
      private Curve3d[] m_crvArray;
      private Point3d[] m_points;
      private int m_polyVCount;
      private int m_distinctCurves;
      private Boolean m_success;
      private Boolean m_compositable;
      private Curve m_curve;
      private Tolerance m_tol;
      private List<Curve3d> m_listCurve3d;

      //Constructors
      public EntityToGeom()
      {
            InitializeConstructor();
      }
      public EntityToGeom(Curve crv)
      {
            InitializeConstructor();
            m_curve = crv;
            ProcessCrv();
      }
      public EntityToGeom(Curve crv, Tolerance DesiredTolerance)
      {
            InitializeConstructor();
            m_curve = crv;
            m_tol = DesiredTolerance;
      }
      //Destructor
      ~EntityToGeom()
      {
            m_curve.Dispose();
      }
      //Properties
      public Boolean ConversionSuccess
      {
            get
            {
                return m_success;
            }
      }

      public int NumOfPolyVerts
      {
            get
            {
                return m_polyVCount;
            }
      }
      public CompositeCurve3d CurveGeometry
      {
            get
            {
                return m_compCurve;
            }
      }
      public Curve DatabaseCurve
      {
            set
            {
                m_curve = value;
                ProcessCrv();
            }
      }
      public Tolerance DesiredTolerance
      {
            set
            {
                m_tol = DesiredTolerance;
            }
            get
            {
                return m_tol;
            }
      }
      //Internal
      private void InitializeConstructor()
      {
            m_success = false;
            m_compositable = true;
            m_tol = new Tolerance();
      }
      private void ProcessCrv()
      {
            string crvTyp = m_curve.GetType().ToString();
            switch (crvTyp)
            {
                case "Autodesk.AutoCAD.DatabaseServices.Line":
                  LineSegment3d ls3d = new LineSegment3d(m_curve.StartPoint, m_curve.EndPoint);
                  m_crvArray = new Curve3d;
                  m_crvArray = ls3d;
                  m_distinctCurves = 1;
                  m_compositable = true;
                  break;
                case "Autodesk.AutoCAD.DatabaseServices.Ray":
                  ProcessConstruction(true);
                  m_compositable = false;
                  m_distinctCurves = 1;
                  break;
                case "Autodesk.AutoCAD.DatabaseServices.XLine":
                  ProcessConstruction(false);
                  m_compositable = false;
                  m_distinctCurves = 1;
                  break;
                case "Autodesk.AutoCAD.DatabaseServices.Circle":
                  ProcessCirculars(false);
                  m_distinctCurves = 1;
                  break;
                case "Autodesk.AutoCAD.DatabaseServices.Arc":
                  ProcessCirculars(true);
                  m_distinctCurves = 1;
                  break;
                case "Autodesk.AutoCAD.DatabaseServices.Ellipse":
                  ProcessEllipticals();
                  m_distinctCurves = 1;
                  break;
                case "Autodesk.AutoCAD.DatabaseServices.Polyline":
                  ProcessPoly(true);
                  break;
                case "Autodesk.AutoCAD.DatabaseServices.Polyline2d":
                  ProcessPoly(false);
                  break;
                case "Autodesk.AutoCAD.DatabaseServices.Polyline3d":
                  ProcessPoly3d();
                  break;
                case "Autodesk.AutoCAD.DatabaseServices.Spline":
                  ProcessSpline();
                  m_distinctCurves = 1;
                  break;
            }
            if (m_compositable)
            {
                try
                {
                  m_compCurve = new CompositeCurve3d(m_crvArray);
                  m_success = true;
                }
                catch
                {
                  m_success = false;
                }
            }
            else
            {
                m_success = false;
            }

      }
      private void ProcessPoly(Boolean LightWeight)
      {
            Polyline2d p2d;
            if (LightWeight)
            {
                Polyline p = m_curve as Polyline;
                p2d = p.ConvertTo(false);
                p.Dispose();
            }
            else
            {
                p2d = m_curve as Polyline2d;
            }
            switch (p2d.PolyType)
            {
                case Poly2dType.SimplePoly:
                  ProcessSimplePolys(p2d);
                  break;
                case Poly2dType.FitCurvePoly:
                  ProcessFitPoly(p2d);
                  break;
                case Poly2dType.QuadSplinePoly:
                  ProcessSplinePoly2d(p2d, 2);
                  break;
                case Poly2dType.CubicSplinePoly:
                  ProcessSplinePoly2d(p2d, 3);
                  break;
            }
            ProcessCurveList();
      }

      private void ProcessPoly3d()
      {
            Polyline3d p3d = m_curve as Polyline3d;
            Database db = HostApplicationServices.WorkingDatabase;
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                PolylineVertex3d pv3d;
                m_polyVCount = Convert.ToInt32(p3d.EndParam);
                m_points = new Point3d;
                int i = 0;
                foreach (ObjectId oid in p3d)
                {
                  pv3d = trans.GetObject(oid, OpenMode.ForRead) as PolylineVertex3d;
                  m_points = pv3d.Position;
                  if (i > 0)
                  {
                        if (!m_points.IsEqualTo(m_points, m_tol))
                        {                        
                            switch (p3d.PolyType)
                            {
                              case Poly3dType.SimplePoly:
                                    m_listCurve3d.Add(new LineSegment3d(m_points, m_points));
                                    m_distinctCurves = m_listCurve3d.Count;
                                    break;
                              case Poly3dType.QuadSplinePoly:
                                    ProcessSplinePoly3d(p3d, 2);
                                    m_distinctCurves = 1;
                                    break;
                              case Poly3dType.CubicSplinePoly:
                                    ProcessSplinePoly3d(p3d, 3);
                                    m_distinctCurves = 1;
                                    break;
                            }
                        }
                  }
                  i++;
                }
                p3d.Dispose();
            }
            ProcessCurveList();
      }
      private void ProcessSpline()
      {
            Spline spl = m_curve as Spline;
            NurbCurve3d nc3d;
            if (spl.HasFitData)
            {
                Vector3dCollection v3c;
                FitData fd = spl.FitData;
                if (fd.TangentsExist)
                {
                  v3c = TangentVectorContainer(fd);
                  nc3d = new NurbCurve3d(fd.GetFitPoints(), v3c, spl.IsPeriodic);
                }
                else
                {
                  nc3d = new NurbCurve3d(fd.GetFitPoints(), new Vector3d(), new Vector3d(), false, false);   
                }
            }
            else
            {
                NurbsData nd = spl.NurbsData;
                DoubleCollection dc = nd.GetKnots();
                KnotCollection kc = new KnotCollection();
                foreach (Double d in dc)
                {
                  kc.Add(d);
                }
                Point3dCollection p3cCP = nd.GetControlPoints();
                if (nd.Rational)
                {
                  DoubleCollection dcw = nd.GetWeights();
                  nc3d = new NurbCurve3d(nd.Degree, kc, p3cCP, dcw, nd.Periodic);
                }
                else
                {
                  nc3d = new NurbCurve3d(nd.Degree, kc, p3cCP, nd.Periodic);
                }
            }
            m_crvArray = new Curve3d;
            m_crvArray = nc3d;
            spl.Dispose();
      }
      private void ProcessConstruction(Boolean StartPoint)
      {
            if (StartPoint)
            {
                Ray r = m_curve as Ray;
                Ray3d r3d = new Ray3d(r.BasePoint, r.SecondPoint);
                m_crvArray = new Curve3d;
                m_crvArray = r3d;
                r.Dispose();
            }
            else
            {
                Xline x = m_curve as Xline;
                Line3d l3d = new Line3d(x.BasePoint, x.SecondPoint);
                m_crvArray = new Curve3d;
                m_crvArray = l3d;
                x.Dispose();
            }
      }
      private void ProcessCirculars(Boolean isArc)
      {
            if (isArc)
            {
                Arc a = m_curve as Arc;
                Double param = (a.StartParam + a.EndParam) / 2;
                Point3d p3d = a.GetPointAtParameter(param);
                CircularArc3d ca3 = new CircularArc3d(a.StartPoint, p3d, a.EndPoint);
                m_crvArray = new Curve3d;
                m_crvArray = ca3;
                a.Dispose();
            }
            else
            {
                Circle c = m_curve as Circle;
                CircularArc3d ca3 = new CircularArc3d(c.Center, c.Normal, c.Radius);
                m_crvArray = new Curve3d;
                m_crvArray = ca3;
                c.Dispose();
            }
      }
      private void ProcessEllipticals()
      {
            Ellipse e = m_curve as Ellipse;
            EllipticalArc3d ea3 = new EllipticalArc3d(e.Center, e.MajorAxis, e.MinorAxis,
                e.MajorRadius, e.MinorRadius, e.StartParam, e.EndParam);
            m_crvArray = new Curve3d;
            m_crvArray = ea3;
            e.Dispose();
      }
      private Vector3dCollection TangentVectorContainer(FitData fd)
      {
            Vector3dCollection v3c = new Vector3dCollection(2);
            v3c.Add(fd.StartTangent);
            v3c.Add(fd.EndTangent);
            return v3c;
      }
      private void ProcessCurveList()
      {
            m_listCurve3d.TrimExcess();
            int i = m_listCurve3d.Count;
            m_crvArray = new Curve3d;
            for (int j = 0; j < i; j++)
            {
                m_crvArray = m_listCurve3d;
            }
            
      }
      private void ProcessSimplePolys(Polyline2d p2d)
      {
            Database db = HostApplicationServices.WorkingDatabase;
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                m_polyVCount = Convert.ToInt32(p2d.EndParam);
                m_points = new Point3d;
                m_listCurve3d = new List<Curve3d>();
                int i = 0;
                Double bulge = 0.0;
                Double param = 0.0;
                foreach (Vertex2d v2d in p2d)
                {
                  m_points = p2d.VertexPosition(v2d);
                  if (i > 0)
                  {
                        if (!m_points.IsEqualTo(m_points, m_tol))
                        {
                            bulge = Math.Round(bulge, 6);
                            if (bulge != 0.0)
                            {
                              param = Convert.ToDouble(i) - 0.5;
                              Point3d pt3 = p2d.GetPointAtParameter(param);
                              m_listCurve3d.Add(new CircularArc3d(m_points, pt3, m_points));
                            }
                            else
                            {
                              m_listCurve3d.Add(new LineSegment3d(m_points, m_points));
                            }
                        }
                  }
                  i++;
                  bulge = v2d.Bulge;
                }
                p2d.Dispose();
            }
      }
      private void ProcessFitPoly(Polyline2d p2d)
      {
            int i = 0;
            Double param;
            foreach (Vertex2d v2d in p2d)
            {
                m_points = p2d.VertexPosition(v2d);
                if (i > 0)
                {
                  if (!m_points.IsEqualTo(m_points, m_tol))
                  {
                        param = Convert.ToDouble(i) - 0.5;
                        Point3d pt3 = p2d.GetPointAtParameter(param);
                        m_listCurve3d.Add(new CircularArc3d(m_points, pt3, m_points));
                  }
                }
                i++;
            }
      }
      private void ProcessSplinePoly2d(Polyline2d p3d, int degree)
      {
      }
      private void ProcessSplinePoly3d(Polyline3d p3d, int degree)
      {
      }
    }
}

雪山飞狐_lzh 发表于 2009-6-20 16:02:00

<p>曲线打断第二版已修正</p>

roamer2000 发表于 2009-8-24 14:57:00

俺综合一下各位的帖子,整理了一下

      public static void TRimByPolyline()
      {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            Polyline cutBox;
            //选择曲线
            PromptEntityResult per = ed.GetEntity("选择边线");
            if (per.Status != PromptStatus.OK) return;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                DBObject pDBObj= tr.GetObject(per.ObjectId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead);//剪切边界实体
                if (pDBObj.GetType().Name.ToString() != "Polyline")
                {
                  MessageBox.Show("选择的不是Polyline线");
                  return;
                }
                cutBox = (Polyline)pDBObj;
                Point3dCollection cutBoxPC = new Point3dCollection();
                for (int i = 0; i < cutBox.NumberOfVertices; i++)
                  cutBoxPC.Add(cutBox.GetPoint3dAt(i));
                PromptSelectionResult res = ed.SelectFence(cutBoxPC, new SelectionFilter(new TypedValue[] { new TypedValue(0, "*Line,Arc,Circle,Ellipse") }));// GetSelection(new PromptSelectionOptions(), new SelectionFilter(new TypedValue[] { new TypedValue(0, "*Line,Arc,Circle,Ellipse") }));
                ObjectId[] ids = res.Value.GetObjectIds();
                ObjectIdCollection oldids = new ObjectIdCollection();
                BlockTableRecord btr =
                  (BlockTableRecord)tr.GetObject(
                        db.CurrentSpaceId,
                        Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite,
                        false);
                //遍历选择集
                foreach (ObjectId i in ids)
                {
                  List<double> pars = new List<double>();
                  Curve iCurve = (Curve)tr.GetObject(i, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead);
                  Point3dCollection iwpnts = new Point3dCollection();
                  iCurve.IntersectWith(cutBox, Intersect.OnBothOperands, iwpnts, 0, 0);
                  foreach (Point3d p in iwpnts)
                  {
                        pars.Add(iCurve.GetParameterAtPoint(p));
                  }
                  //如果有交点,按param值排序并打断
                  if (pars.Count > 0)
                  {
                        pars.Sort();
                        try
                        {
                            //将子曲线加入数据库,原曲线加入oldids集合
                            foreach (Curve c in iCurve.GetSplitCurves(new DoubleCollection(pars.ToArray())))
                            {
                              btr.AppendEntity(c);
                              tr.AddNewlyCreatedDBObject(c, true);
                            }
                            oldids.Add(i);
                        }
                        catch
                        { }
                  }
                }
                foreach (ObjectId id in oldids)
                {
                  tr.GetObject(id, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite).Erase();
                }
                tr.Commit();
            }
      }

可是在附件里运行出现各种错误,还希望各位指点

雪山飞狐_lzh 发表于 2009-8-24 15:20:00

裁剪的话,以前给网友改过类似的
下面一段是打断的例程,当然,后续的判断部分要自己加

        
        public static void plqt()//批量裁剪图幅
        {
            TypedValue[] txtvalue = { new TypedValue((int)DxfCode.Start, "LWPOLYLINE")};
            SelectionFilter flter = new SelectionFilter(txtvalue);
            PromptSelectionResult myset = TlsTM.Editor.GetSelection(flter);
            if (myset.Status == PromptStatus.OK)
            {
                #region//搜索边界
                using (TlsETM tm = new TlsETM())
                {
                    tm.OpenCurrentSpace();
                    foreach (ObjectId id in myset.Value.GetObjectIds())
                    {
                        Entity myent = (Entity)tm.GetObject(id, OpenMode.ForRead);
                        if (myent.GetType().Name == "olyline")
                        {
                            #region//取得打断边界实体
                            Curve iCurve = (Curve)myent;
                            #endregion
                            #region//开始打断实体
                            TypedValue[] ent = { new TypedValue(0, "*Line,Arc,Circle,Ellipse") };
                            SelectionFilter terf = new SelectionFilter(ent);
                            PromptSelectionResult entRes = TlsTM.Editor.SelectAll(terf);
                            DBObjectCollection myobjCol = new DBObjectCollection();

                            foreach (ObjectId myid in entRes.Value.GetObjectIds())
                            {
                                List<oint3d> pnts = new List<oint3d>();
                                List<double> dists = new List<double>();
                                if (id != myid)
                                {
                                    Curve jCurve = (Curve)tm.GetObject(myid, OpenMode.ForWrite);
                                    Point3dCollection ptcol = new Point3dCollection();
                                    jCurve.IntersectWith(iCurve, Intersect.OnBothOperands, ptcol, 0, 0);
                                    foreach (Point3d p in ptcol)
                                    {
                                        pnts.Add(p);

                                        dists.Add(jCurve.GetDistAtPoint(p));
                                    }//endforeach
                                    if (pnts.Count > 0)
                                    {
                                        Point3d[] pntarr = pnts.ToArray();
                                        Array.Sort(dists.ToArray(), pntarr);
                                        try
                                        {
                                            myobjCol = jCurve.GetSplitCurves(new Point3dCollection(pntarr));
                                            foreach (DBObject obj in myobjCol)
                                            {
                                                Entity ee = (Entity)obj;
                                                tm.AddEntity(ee);
                                            }
                                        }
                                        catch
                                        {
                                        }
                                    }
                                }
                            #endregion
                            }//end foreach
                        }//end if
                    }//end foreach
                }//endusing
                #endregion//搜索边界
            }
            else
                return;//end if
        }//end void

roamer2000 发表于 2009-8-24 16:41:00

<p>一样的错误{"eInvalidInput"}</p><p>在这句dists.Add(jCurve.GetDistAtPoint(p));</p><p>pars.Add(iCurve.GetParameterAtPoint(p));</p>

雪山飞狐_lzh 发表于 2009-8-24 17:12:00

用GetClosestPointTo函数获取曲线上的最近点,DB曲线有这样的Bug

roamer2000 发表于 2009-8-25 14:04:00

作为打断点?

雪山飞狐_lzh 发表于 2009-8-25 14:11:00

<p>DB曲线的GetXXX函数是有误差的,有时会出现获取的点不在曲线上,用GetClosestPointTo消除<br/>但在曲线很短的时候会出现获取的点缺失<br/>建议把DB曲线转换为Ge曲线操作,上面的帖子以及我的TlsBasal类和曲线转换类有相关的例程,你可以看下<br/></p>

tomcom 发表于 2009-8-26 10:13:00

<p>谢谢楼主提供材料!</p>
页: 1 2 [3] 4 5 6
查看完整版本: 曲线处理专贴----我们的[原创]