Тема: Удаление точки из AcDb3dPolyline

Если удалить точку из AcDb3dPolyline, то после запуска команды 3dorbit она опять появляется, и исчезает после выхода из команды.
Реализация удаления:
1. Итератором прохожу по точкам.
2. Нахожу нужный AcDbObjectId точки
3. Открываю точку
4. Вызываю erase
5. Закрываю точку
Команда 3dorbit не видит что точка удалена.
Может есть у кого-то уже решение ?той проблемки?
Буду очень благодарен.

Re: Удаление точки из AcDb3dPolyline

А итератор ты уничтожил до удаления вершины или после? Это первая вершина или нет? Открывал вершину на запись или нет? Выложи код - посмотрим.

Re: Удаление точки из AcDb3dPolyline

Еще заметил, что удалять нужно точку с z!=0
В этом примере удаляется вторая точка 3d линии

void LinePntDel()        //удалить точку линии
{
    ads_name ssName;
    ads_point ptres;
    int nRet = acedEntSel("\nУкажите 3d полилинию: ", ssName, ptres);    
    if(nRet!=RTNORM) {
        acutPrintf("\nЛиния не выбрана!");
        return;
    }
    
    AcDbObjectId lineId;
    acdbGetObjectId(lineId, ssName);
    
    AcDbObjectPointer<AcDb3dPolyline> pPoly(lineId, AcDb::kForWrite);
    if (pPoly.openStatus() != Acad::eOk) return;
    //Удаляем вторую - найти AcDbObjectId
    AcDbObjectId vtxId;
    AcDbObjectIterator *pVtxIt = pPoly->vertexIterator();
    int i=0;
    for(pVtxIt->start(); !pVtxIt->done(); pVtxIt->step()){
        if(pVtxIt->objectId().isErased()) continue;
        if(i++==1) vtxId=pVtxIt->objectId();
    }
    delete pVtxIt;
    if(vtxId==AcDbObjectId::kNull){
        acutPrintf("\nУдаление не возможно ");
        return;
    }
    //Удалить
    AcDbObjectPointer<AcDb3dPolylineVertex> pVtx(vtxId, AcDb::kForWrite);
    if (pVtx.openStatus() != Acad::eOk) return;
    pVtx->erase();
    
    acutPrintf("\nТочка удалена ");
}//LinePntDel

Re: Удаление точки из AcDb3dPolyline

Измени:

 AcDbObjectPointer<AcDb3dPolyline> pPoly(lineId, AcDb::kForWrite);

на

AcDbObjectPointer<AcDb3dPolyline> pPoly(lineId, AcDb::kForRead);

А еще лучше - закрой полилинию до удаления вершины сразу после создания итератора.

Re: Удаление точки из AcDb3dPolyline

Изменил на kForRead и закрыл полилинию сразу после создания итератора.
Не помагает. 3dorbit не видит все-равно что точка удалена.

Re: Удаление точки из AcDb3dPolyline

Проверил. Оказалось чуть-чуть сложнее. Лови:

  static void VertexDelVertexDel(void)
  {
    // Add your code for command VertexDel.VertexDel here
    ads_name ssName;
    ads_point ptres;
    int nRet = acedEntSel("\nУкажите 3d полилинию: ", ssName, ptres);
    if(nRet!=RTNORM) {
      acutPrintf("\nЛиния не выбрана!");
      return;
    }
    AcDbObjectId lineId;
    AcDbObjectIterator *pVtxIt = NULL;
    AcDbObjectIdArray aVtxIds;
    int iVtx = 1;
    if (acdbGetObjectId(lineId, ssName) == Acad::eOk)  {
      AcDbObjectPointer<AcDb3dPolyline> pPoly(lineId, AcDb::kForWrite);
      if (pPoly.openStatus() != Acad::eOk) return;
      pVtxIt = pPoly->vertexIterator();
      AcDbObjectId firstId = pVtxIt->objectId();
      if(pVtxIt->objectId().isErased()) {
        pVtxIt->step();
        firstId = pVtxIt->objectId();
      }
      for (pVtxIt->setPosition(firstId); !pVtxIt->done(); pVtxIt->step()){
        if(pVtxIt->objectId().isErased()) continue;
        aVtxIds.append(pVtxIt->objectId());
      }
      delete pVtxIt;
    } else return;
    char prompt[128]="";
    sprintf(prompt,"\nУкажите номер вершины (1 - %d): ",aVtxIds.length());
    Acad:ErrorStatus es;
    while (acedGetInt(prompt,&iVtx) == RTNORM && (iVtx < 1 || iVtx > aVtxIds.length())) {
      acutPrintf("\nТакой вершины нет. Повторите!!!");
    }
    if (iVtx >= 1 && iVtx <= aVtxIds.length()) {
      actrTransactionManager->startTransaction();
      {
         AcDbObjectPointer<AcDb3dPolylineVertex> pVt(aVtxIds[iVtx-1], AcDb::kForWrite);
         if (pVt.openStatus() == Acad::eOk) {
          es = pVt->erase(true);
          if (es != Acad::eOk) {
           acutPrintf("\nОшибка удаления вершины: %s", acadErrorStatusText(es));
          }
         }
      }
      actrTransactionManager->endTransaction();
      actrTransactionManager->startTransaction();
      {
        AcDbObjectPointer<AcDb3dPolyline> pPoly(lineId, AcDb::kForWrite);
        if (pPoly.openStatus() == Acad::eOk) {
          pPoly->recordGraphicsModified(true);
        }
      }
      actrTransactionManager->endTransaction();
    }
 }

Re: Удаление точки из AcDb3dPolyline

Смысл всех этих манипуляций - заставить 3DORBIT ловить новую графику (без удаленной вершины). А для этого необходимо выполнитьpPoly->recordGraphicsModified(true);
Транзакции в принципе здесь не обязательны. IMHO такое поведение - это глюк AutoCAD.

Re: Удаление точки из AcDb3dPolyline

Спасибо.

Re: Удаление точки из AcDb3dPolyline

Извините, что поднимаю старую тему, но почему нельзя здесь использовать "removeVertexAt()"?

Re: Удаление точки из AcDb3dPolyline

> aazko
Попробуй. Проблема была в том, что той версии AutoCAD в 3DORBIT удаленная вершина все равно была видна и все эти трюки были связаны с желанием обойти этот баг в AutoCAD. В более поздних версиях не проверял.

Re: Удаление точки из AcDb3dPolyline

Попробовал. Удаляю вершины через "removeVertexAt()". AutoCAD 2002. Проблем пока нет.

Re: Удаление точки из AcDb3dPolyline

> aazko
А ты не перепутал AcDbPolyline и AcDb3dPolyline? :)

Re: Удаление точки из AcDb3dPolyline

Вы, как всегда, правы.
... Да уж, не сообразил. У меня испльзуются пока только 2-х мерные полилинии. Уже к ним привык, даже особо и не смотрел на объяление указателей. :(