Есть такой вариант. Это не совсем TRIM, а скорее BREAK (т.е. команда разрывает кривую на две по указанной точке), но может быть пригодится. Этот метод не работает для CIRCLE - нужна отдельная обработка.
static void CurveTrim(void)
{
ads_name en;
ads_point p;
if (acedEntSel("\nВыберите кривую для обрезки: ",en,p) == RTNORM) {
AcDbObjectId objId; acdbGetObjectId(objId,en);
AcDbObjectPointer<AcDbCurve> pCurv(objId,AcDb::kForRead);
if (pCurv.openStatus() != Acad::eOk) {
acutPrintf("\nВыбрана не кривая!");
return;
}
if (acedGetPoint(p,"\nУкажите точку на линии для обрезки: ",p) != RTNORM) {
acutPrintf("\nТочка не указана!");
return;
}
// Преобразуем точку из UCS->WCS
acdbUcs2Wcs(p,p,0);
AcGePoint3d trimPnt(asPnt3d(p));
Acad::ErrorStatus es;
double dist; es = pCurv->getDistAtPoint(trimPnt,dist);
if (es != Acad::eOk && (es = pCurv->getClosestPointTo(trimPnt,trimPnt)) != Acad::eOk) {
acutPrintf("\nОшибка getClosestPointTo: %s",acadErrorStatusText(es));
return;
}
AcGePoint3dArray trimPoints; trimPoints.append(trimPnt);
AcDbVoidPtrArray newCurves;
if ((es = pCurv->getSplitCurves(trimPoints,newCurves)) != Acad::eOk) {
acutPrintf("\nОшибка getSplitCurves: %s",acadErrorStatusText(es));
return;
}
// Добавляем новые кривые
for (int i=0; i < newCurves.length(); i++) {
AcDbEntity *pSplCurv = (AcDbEntity *)newCurves[i];
if (postToDatabase(pCurv->blockId(),pSplCurv)) {
pSplCurv->close();
} else {
delete pSplCurv;
}
}
// Удаляем старую кривую
if (pCurv->upgradeOpen() == Acad::eOk) {
pCurv->erase();
}
}
}
static bool postToDatabase (AcDbObjectId blockId, AcDbEntity *pEntity)
{
if (pEntity) {
AcDbBlockTableRecordPointer pBlk(blockId, AcDb::kForWrite) ;
if (pBlk.openStatus () != Acad::eOk) return (false) ;
return (pBlk->appendAcDbEntity (pEntity) == Acad::eOk) ;
}
return (false);
}