Тема: Как реализовать метод trim для AcDbpolyline?

Здравствуйте, у AcDbCurve и ниже по дереву, есть метод extend, а как реализовать метод trim??? Я сейчас делаю так: Руками отследить с помощью intersectWith точку пересечения и методами объекта потом его самого же и обрезать. У AcDbPolyline удалить все точки, которые лежат, например, слева от точки пересечения. Это правильно или есть какой-то более лаконичный подход???
Большое спасибо, Алексеев

Re: Как реализовать метод trim для AcDbpolyline?

Есть такой вариант. Это не совсем 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);
}

Re: Как реализовать метод trim для AcDbpolyline?

А вот усовершенствованный вариант:

static void CurveTrim(void)
{
  ads_name en;
  ads_point p,p1;
  if (acedEntSel("\nВыберите кривую для обрезки с той стороны, которая останется: ",en,p1) == RTNORM) {
    AcDbObjectId objId; acdbGetObjectId(objId,en);
    AcDbObjectPointer<AcDbCurve> pCurv(objId,AcDb::kForRead);
    if (pCurv.openStatus() != Acad::eOk) {
      acutPrintf("\nВыбрана не кривая!");
      return;
    }
    if (acedGetPoint(p1,"\nУкажите точку на линии для обрезки: ",p) != RTNORM) {
      acutPrintf("\nТочка не указана!");
      return;
    }
    // Преобразуем точку из UCS->WCS
    acdbUcs2Wcs(p,p,0); acdbUcs2Wcs(p1,p1,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;
    }
    AcGePoint3d pointOnCurv(asPnt3d(p1));
    pCurv->getClosestPointTo(pointOnCurv,pointOnCurv);
    for (int i=0; i < newCurves.length(); i++) {
      AcDbCurve *pSplCurv = (AcDbCurve *)newCurves[i];
      // Добавляем кривую, которая проходит через точку pointOnCurv
      if (pSplCurv->getDistAtPoint(pointOnCurv,dist) == Acad::eOk) {
        if (pCurv->upgradeOpen() == Acad::eOk) {
          pCurv->handOverTo(pSplCurv); pSplCurv->close();
          if (pCurv.release(pSplCurv) == Acad::eOk) {
            delete pSplCurv;
          }
        }
        break;
      } else {
        delete pSplCurv;
      }
    }
  }
}