发现问题在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)
{
}
}
} <p>曲线打断第二版已修正</p>
俺综合一下各位的帖子,整理了一下
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();
}
}
可是在附件里运行出现各种错误,还希望各位指点 裁剪的话,以前给网友改过类似的
下面一段是打断的例程,当然,后续的判断部分要自己加
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
<p>一样的错误{"eInvalidInput"}</p><p>在这句dists.Add(jCurve.GetDistAtPoint(p));</p><p>pars.Add(iCurve.GetParameterAtPoint(p));</p> 用GetClosestPointTo函数获取曲线上的最近点,DB曲线有这样的Bug 作为打断点? <p>DB曲线的GetXXX函数是有误差的,有时会出现获取的点不在曲线上,用GetClosestPointTo消除<br/>但在曲线很短的时候会出现获取的点缺失<br/>建议把DB曲线转换为Ge曲线操作,上面的帖子以及我的TlsBasal类和曲线转换类有相关的例程,你可以看下<br/></p> <p>谢谢楼主提供材料!</p>