Glad you got a solution and yes i realize that, here is my old code, in case someone finds it useful.
typedef std::vector<AcGePoint3d> PointList;
const double kPi = 3.14159265358979323846;
Acad::ErrorStatus MakeTempLWPoly (AcDb2dPolyline* tmp2dPoly, AcGePoint3dArray &pts, AcDbVoidPtrArray &curveSegments)
{
Acad::ErrorStatus es;
AcDbObjectId curSpaceId = acdbCurDwg()->currentSpaceId();
AcDbBlockTableRecord *pBlkRec = NULL;
AcDbCurve* tmpCurve;
AcGePoint3dArray vertices;
AcGeDoubleArray bulges;
AcDb2dVertex* vert = NULL;
AcDbObjectId vId;
double c = 0;
AcDbObjectIterator *vIter;
double parametro;
vIter = tmp2dPoly->vertexIterator();
for (; !vIter->done(); vIter->step())
{
vId = vIter->objectId();
if (tmp2dPoly->openVertex(vert, vId, AcDb::kForRead) == Acad::eOk)
{
if (tmp2dPoly->getParamAtPoint(vert->position(), parametro) == Acad::eOk)
{
c = vert->bulge();
if ((tmp2dPoly->normal()-AcGeVector3d::kZAxis).length() > 1E-6) c *= -1.0;
vertices.append(tmp2dPoly->vertexPosition(*vert));
bulges.append(c);
}
vert->close();
}
}
if (tmp2dPoly->isClosed())
{
if (vertices.first() != vertices.last())
{
vertices.append(vertices.first());
bulges.append(bulges.first());
}
}
delete vIter;
Adesk::Boolean closed;
if (tmp2dPoly->isClosed())
{
closed = Adesk::kTrue;
}
else
{
closed = Adesk::kFalse;
}
AcCmColor col = tmp2dPoly->color();
ACHAR* ltype = tmp2dPoly->linetype();
AcDbPolyline* pBreakLine = new AcDbPolyline(vertices.length());
for (int i=0; i < vertices.length(); i++)
{
AcGePoint2d pt;
pt.set(vertices.at(i).x,vertices.at(i).y);
pBreakLine->addVertexAt(i,pt,bulges.at(i));
}
pBreakLine->setClosed(closed);
pBreakLine->setColor(col);
pBreakLine->setLinetype(ltype);
acutDelString(ltype);
vertices.removeAll();
bulges.removeAll();
es = pBreakLine->getSplitCurves(pts,curveSegments);
if (es == Acad::eOk)
{
for (int i=0; i < curveSegments.length(); i++)
{
tmpCurve = static_cast<AcDbCurve*>(curveSegments[i]);
if (tmpCurve)
{
if (acdbOpenObject(pBlkRec,curSpaceId,AcDb::kForWrite) == Acad::eOk)
{
pBlkRec->appendAcDbEntity(tmpCurve);
pBlkRec->close();
tmpCurve->close();
}
}
}
curveSegments.removeAll();
}
else
{
for (int i = 0; i < curveSegments.length(); i++)
{
tmpCurve = static_cast<AcDbCurve*>(curveSegments[i]);
delete tmpCurve;
}
curveSegments.removeAll();
}
pBreakLine->close();
delete pBreakLine;
return es;
}
static void SplitCurves (void)
{
AcDbObjectId curSpaceId = acdbCurDwg()->currentSpaceId();
AcDbBlockTableRecord *pBlkRec = NULL;
AcDbCurve* tmpCurve;
AcGePoint3dArray pts;
AcDbVoidPtrArray curveSegments;
AcGePoint3dArray ints;
AcGePoint3dArray duplicates;
PointList points;
Acad::ErrorStatus es;
ads_name ss1;
AcDbObjectIdArray ids;
resbuf *rbFilter = acutBuildList(RTDXF0, _T("LINE,ARC,LWPOLYLINE,POLYLINE,CIRCLE,SPLINE,ELLIPSE"), RTNONE);
if (acedSSGet(NULL, NULL, NULL, rbFilter, ss1) != RTNORM)
{
acutRelRb(rbFilter);
return;
}
acutRelRb(rbFilter);
long length1 = 0;
if ((acedSSLength(ss1, &length1) != RTNORM) || (length1 == 0))
{
acedSSFree(ss1);
return;
}
for (UINT i = 0; i < length1; i++)
{
AcDbObjectId oid;
ads_name ename;
acedSSName(ss1, i, ename);
if (acdbGetObjectId(oid, ename) != Acad::eOk) return;
AcDbObjectPointer<AcDbCurve> pPoly(oid, AcDb::kForWrite);
if (pPoly.openStatus() == Acad::eOk)
{
ids.append(oid);
AcDbExtents ebox;
pPoly->getGeomExtents(ebox);
AcGePoint3d ll, ur;
ll = ebox.minPoint();
ur = ebox.maxPoint();
acdbWcs2Ucs(asDblArray(ll), asDblArray(ll), false);
acdbWcs2Ucs(asDblArray(ur), asDblArray(ur), false);
ads_point ptres, a, b;
AcGePoint3d m;
double d = (sqrt(2.0) * acutDistance(asDblArray(ll), asDblArray(ur)) / 2.0);
acutPolar(asDblArray(ll), acutAngle(asDblArray(ll), asDblArray(ur)),
acutDistance(asDblArray(ll), asDblArray(ur)), asDblArray(m));
acutPolar(asDblArray(m), ((3 * kPi) / 4), d, ptres);
acdbWcs2Ucs(ptres, a, false);
acutPolar(asDblArray(m), ((7 * kPi) / 4), d, ptres);
acdbWcs2Ucs(ptres, b, false);
ads_name ss2;
resbuf *rbFilter = acutBuildList(RTDXF0, _T("LINE,ARC,LWPOLYLINE,POLYLINE,CIRCLE,SPLINE,ELLIPSE"), RTNONE);
if (acedSSGet(_T("_C"), asDblArray(ll), asDblArray(ur), rbFilter, ss2) != RTNORM)
//if (acedSSGet(_T("_C"), a, b, rbFilter, ss2) != RTNORM)
{
acutRelRb(rbFilter);
return;
}
acutRelRb(rbFilter);
acedSSDel(ename, ss2);
long length2 = 0;
if ((acedSSLength(ss2, &length2) != RTNORM) || (length2 == 0))
{
acedSSFree(ss2);
return;
}
for (UINT i = 0; i < length2; i++)
{
AcDbObjectId oid;
ads_name ename;
acedSSName(ss2, i, ename);
if (acdbGetObjectId(oid, ename) != Acad::eOk) return;
AcDbObjectPointer<AcDbCurve> pEnt(oid, AcDb::kForRead);
if (pEnt.openStatus() == Acad::eOk)
{
if (pPoly->intersectWith(pEnt.object(), AcDb::kOnBothOperands, ints) == Acad::eOk)
{
if (!ints.isEmpty())
{
for (UINT i = 0; i < ints.length(); i++)
{
if (!duplicates.contains(ints.at(i)))
{
duplicates.append(ints.at(i));
points.push_back(ints.at(i));
}
else
continue;
}
}
}
}
}
acedSSFree(ss2);
if (!points.empty())
{
vector<double> distances;
map<double, AcGePoint3d> m;
double dist;
for (UINT i = 0; i < points.size(); i++)
{
AcGePoint3d pt = points.at(i);
if (pPoly->getDistAtPoint(pt, dist) == Acad::eOk)
{
m.insert(make_pair(dist, pt));
distances.push_back(dist);
}
}
map<double, AcGePoint3d>::const_iterator it;
int cnt = 0;
std::sort(distances.begin(), distances.end());
std::vector<AcGePoint3d> _points;
for (it = m.begin(); it != m.end(); ++it)
{
AcGePoint3d pt;
it = m.find(distances.at(cnt));
pt = (*it).second;
_points.push_back(pt);
cnt = (1 + cnt);
}
m.clear();
distances.clear();
for (UINT i = 0; i < _points.size(); i++)
{
AcGePoint3d pt;
pt = _points.at(i);
acdbWcs2Ucs(asDblArray(pt), asDblArray(pt), false);
pts.append(pt);
}
if (pPoly->isKindOf(AcDb2dPolyline::desc()))
{
AcDb2dPolyline *tmp2dPoly = AcDb2dPolyline::cast((AcRxObject*)pPoly.object());
switch (tmp2dPoly->polyType())
{
case AcDb::k2dSimplePoly:
if (pPoly->getSplitCurves(pts, curveSegments) == Acad::eOk)
{
for (UINT i = 0; i < curveSegments.length(); i++)
{
tmpCurve = static_cast<AcDbCurve*>(curveSegments[i]);
if (tmpCurve)
{
if (acdbOpenObject(pBlkRec, curSpaceId, AcDb::kForWrite) == Acad::eOk)
{
pBlkRec->appendAcDbEntity(tmpCurve);
pBlkRec->close();
tmpCurve->close();
}
}
}
curveSegments.removeAll();
}
else
{
for (UINT i = 0; i < curveSegments.length(); i++)
{
tmpCurve = static_cast<AcDbCurve*>(curveSegments[i]);
delete tmpCurve;
}
curveSegments.removeAll();
}
break;
case AcDb::k2dFitCurvePoly:
MakeTempLWPoly(tmp2dPoly, pts, curveSegments);
break;
case AcDb::k2dQuadSplinePoly:
MakeTempLWPoly(tmp2dPoly, pts, curveSegments);
break;
case AcDb::k2dCubicSplinePoly:
MakeTempLWPoly(tmp2dPoly, pts, curveSegments);
break;
}
}
else
{
if (pPoly->getSplitCurves(pts, curveSegments) == Acad::eOk)
{
for (UINT i = 0; i < curveSegments.length(); i++)
{
tmpCurve = static_cast<AcDbCurve*>(curveSegments[i]);
if (tmpCurve)
{
if (acdbOpenObject(pBlkRec, curSpaceId, AcDb::kForWrite) == Acad::eOk)
{
pBlkRec->appendAcDbEntity(tmpCurve);
pBlkRec->close();
tmpCurve->close();
}
}
}
curveSegments.removeAll();
}
else
{
for (UINT i = 0; i < curveSegments.length(); i++)
{
tmpCurve = static_cast<AcDbCurve*>(curveSegments[i]);
delete tmpCurve;
}
curveSegments.removeAll();
}
}
_points.clear();
points.clear();
}
if (!ints.isEmpty())
ints.removeAll();
if (!duplicates.isEmpty())
duplicates.removeAll();
if (!curveSegments.isEmpty())
curveSegments.removeAll();
if (!pts.isEmpty())
pts.removeAll();
}
}
acedSSFree(ss1);
if (!ids.isEmpty())
{
for (UINT i = 0; i < ids.length(); i++)
{
AcDbObjectPointer<AcDbEntity> pEnt(ids[i], AcDb::kForWrite);
if (pEnt.openStatus() == Acad::eOk)
{
pEnt->erase();
}
}
ids.removeAll();
}
} Also, a simple version in C#:
#region Split Curves
[CommandMethod("SPLITCURVES")]
public void cmd_splitCurves()
{
var editor = AcadApp.DocumentManager.MdiActiveDocument.Editor;
var tv = new[] { new TypedValue((int)DxfCode.Start, "LINE,ARC,LWPOLYLINE,POLYLINE,CIRCLE,SPLINE,ELLIPSE") };
var filter = new SelectionFilter(tv);
const string curveObjects = "curve objects";
var options = new PromptSelectionOptions
{
MessageForAdding = string.Format("\nAdd {0} to selection", curveObjects),
MessageForRemoval = string.Format("\nRemove {0} from selection", curveObjects),
AllowDuplicates = false,
RejectObjectsFromNonCurrentSpace = true
};
var mainSelection = editor.GetSelection(options, filter);
if (mainSelection.Status != PromptStatus.OK) return;
using (var transaction = editor.Document.Database.TransactionManager.StartTransaction())
{
var blockTableRecord = transaction.GetObject(editor.Document.Database.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
if (blockTableRecord != null)
{
foreach (var mainObjectId in mainSelection.Value.GetObjectIds())
{
var points = new Point3dCollection();
var dictionary = new SortedDictionary<double, Point3d>();
var mainCurve = transaction.GetObject(mainObjectId, OpenMode.ForWrite) as Curve;
if (mainCurve == null) continue;
var extents = mainCurve.GeometricExtents;
var minPoint = extents.MinPoint;
var maxPoint = extents.MaxPoint;
var subSelection = editor.SelectCrossingWindow(minPoint, maxPoint, filter);
if (subSelection.Status != PromptStatus.OK) continue;
foreach (var subObjectId in subSelection.Value.GetObjectIds())
{
var subCurve = transaction.GetObject(subObjectId, OpenMode.ForRead) as Curve;
if (subCurve == null) continue;
var intersections = new Point3dCollection();
mainCurve.IntersectWith(subCurve, Intersect.OnBothOperands, intersections, IntPtr.Zero, IntPtr.Zero);
if (intersections.Count <= 0) continue;
foreach (Point3d intersection in intersections)
{
if (points.Contains(intersection)) continue;
points.Add(intersection);
}
}
subSelection.Value.Dispose();
if (points.Count <= 0) continue;
foreach (Point3d point in points)
{
var distance = mainCurve.GetDistAtPoint(point);
if (dictionary.ContainsKey(distance)) continue;
dictionary.Add(distance, point);
}
if (!dictionary.Any()) continue;
var splitPoints = new Point3dCollection(dictionary.Values.ToArray());
var splitCurves = mainCurve.GetSplitCurves(splitPoints);
foreach (DBObject splitCurve in splitCurves)
{
var curve = splitCurve as Curve;
if (curve == null) continue;
blockTableRecord.AppendEntity(curve);
transaction.AddNewlyCreatedDBObject(curve, true);
}
}
}
transaction.Commit();
}
}
#endregion HTH.