Сообщество программистов Autodesk в СНГ

ADN Club => ObjectARX => Тема начата: Эд от 02-04-2017, 17:58:41

Название: Удаление графических объектов
Отправлено: Эд от 02-04-2017, 17:58:41
Не нашел самостоятельно как правильно програмно удалять графические объекты из чертежа (аналогично команде пользователя _ERASE), поэтому применяю Entity.erase(). Прочитал в справочнике что эта функция удаляет объект, но не удаляет его из базы. Что это значит не могу догадаться. Надо найти функцию, которая удаляет объект из базы тоже?
Кроме того пользователю после этого плагина нужно выполнить регенерацию чертежа чтобы изображения стертых объектов исчезло окончательно. Если я правильно сделал то как заставить регенерироваться рисунок или места где были стертые объекты.
И не работает также команда отмена для удаленных объектов.
Название: Re: Удаление графических объектов
Отправлено: Александр Ривилис от 02-04-2017, 18:11:50
Прочитал в справочнике что эта функция удаляет объект, но не удаляет его из базы. Что это значит не могу догадаться. Надо найти функцию, которая удаляет объект из базы тоже?
Не надо ничего искать. Удалённые примитивы помечаются как удалённые и не используются в операциях отображения (так же как и в других операциях). При сохранении чертежа они в него не сохраняются и таким образом освобождается место.
Кроме того пользователю после этого плагина нужно выполнить регенерацию чертежа чтобы изображения стертых объектов исчезло окончательно. Если я правильно сделал то как заставить регенерироваться рисунок или места где были стертые объекты.
Например, при помощи недокументированной функции ads_regen();
Код - C++ [Выбрать]
  1. // Вставляем описание ads_regen:
  2. void ads_regen(void);
Название: Re: Удаление графических объектов
Отправлено: Эд от 02-04-2017, 18:31:13
С регенерацией получилось, но команда _UNDO не работает, что не так?
Вот у меня проект плагина который удаляет однострочные тексты и вставляет на их место многострочные тексты.
Код - C++ [Выбрать]
  1.         static void CTx2Mtx_tx2mtx(void)
  2.         {
  3.                 struct resbuf eb;
  4.                 TCHAR sbuf[10];
  5.                 eb.restype=0; // имя примитива
  6.                 _tcscpy(sbuf,_T("TEXT"));
  7.                 eb.resval.rstring=sbuf;
  8.                 eb.rbnext=0;
  9.                 ads_name ss;
  10.                 if (acedSSGet (ACRX_T("_I"), NULL, NULL, &eb, ss) != RTNORM )
  11.                 {
  12.                         if(acedSSGet(0,0,0,&eb,ss) !=RTNORM)
  13.                         {
  14.                                 //acutRelRb(&eb);
  15.                                 return;
  16.                         }
  17.  
  18.                 }
  19.                 //acutRelRb(&eb);
  20.  
  21.                 long length=0;
  22.                 if((acedSSLength(ss,&length)!=RTNORM)||(length==0))
  23.                 {
  24.                         acedSSFree(ss);
  25.                         return;
  26.                 }
  27.  
  28.                 // Код
  29.                 ads_name ent;
  30.                 AcDbObjectId id = AcDbObjectId::kNull;
  31.                 // Walk through the selection set and open each entity
  32.                 for (long i = 0; i < length; i++)
  33.                 {
  34.                         if (acedSSName(ss,i,ent) != RTNORM) continue;
  35.                         if (acdbGetObjectId(id,ent) != Acad::eOk) continue;
  36.                         AcDbEntity* pEnt = NULL;
  37.                         if (acdbOpenAcDbEntity(pEnt,id,AcDb::kForWrite) != Acad::eOk)
  38.                                 continue;
  39.                         if ( !pEnt->isKindOf (AcDbText::desc ()) )
  40.                         {
  41.                                 pEnt->close();
  42.                                 continue;
  43.                         }
  44.  
  45.                         AcDbText* pT=AcDbText::cast(pEnt);
  46.                         AcDbMText* pMt=new AcDbMText();
  47.                         pMt->setPropertiesFrom(pEnt); //копирование Color, Layer, Linetype, Linetype scale, Visibility
  48.  
  49.                         {AcGePoint3d Point=pT->position();
  50.                                 pMt->setLocation(Point);
  51.                         }
  52.  
  53.  
  54.                         {//AcGePlane plan;
  55.                                 AcGeVector3d Norm=pT->normal();
  56.                                 //AcDb::Planarity curvConfig;
  57.                                 //pT->getPlane(plan,curvConfig);
  58.                                 pMt->setNormal(Norm);
  59.                         }
  60.                         {
  61.                                 double Heitgh=pT->height();
  62.                                 pMt->setTextHeight(Heitgh);
  63.                         }
  64.                         {
  65.                                 double rot=pT->rotation();
  66.                                 pMt->setRotation(rot);
  67.                         }
  68.                         {
  69.                                 AcDbObjectId textstyle=pT->textStyle();
  70.                                 pMt->setTextStyle(textstyle);
  71.                         }
  72.                         {
  73.                                 //const ACHAR* content=pT->textStringConst();
  74.                                 ACHAR* content=pT->textString();
  75.                                 pMt->setContents(content);
  76.                                 acdbFree (content);
  77.                         }
  78.                         //2.pText->setBackgroundFill(true);
  79.                         //3.pText->setUseBackgroundColor(false);
  80.                         //4.pText->setBackgroundScaleFactor(1.0);
  81.                         //5.pText->setBackgroundFillColor(backColor);
  82.                         //10.pText->setAttachmentMovingLocation(AlignLoc);
  83.  
  84.                         AcDbBlockTable *pBlockTable;
  85.                         acdbHostApplicationServices()->workingDatabase()
  86.                                 ->getSymbolTable(pBlockTable, AcDb::kForRead);
  87.                         AcDbBlockTableRecord *pBlockTableRecord;
  88.                         pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);
  89.                         pBlockTable->close();
  90.                         //AcDbObjectId tempId;
  91.                         //pBlockTableRecord->appendAcDbEntity(tempId,pMt);
  92.                         pBlockTableRecord->appendAcDbEntity(pMt);
  93.                         pBlockTableRecord->close();
  94.  
  95.  
  96.                         pMt->close();
  97.                         pEnt->erase(); pEnt=0; 
  98.                 }
  99.                 acedSSFree(ss);
  100.                 ads_regen();
  101.                 return;
  102.         }
  103.  
Название: Re: Удаление графических объектов
Отправлено: Эд от 02-04-2017, 18:40:28
Виноват, последние строчки надо было так написать:
..............
Код - C++ [Выбрать]
  1.                         pMt->close();
  2.                         pEnt->erase();
  3.                         pEnt->close();
  4.                         pEnt=0;
  5.                 }
  6.                 acedSSFree(ss);
  7.                 ads_regen();
  8.                 return;
  9.         }
  10.        
  11. }
Название: Re: Удаление графических объектов
Отправлено: Александр Ривилис от 02-04-2017, 19:02:47
Прочитай про правило форматирования кода на форуме у меня в подписи и неуклонно выполняй его.
Название: Re: Удаление графических объектов
Отправлено: Александр Ривилис от 02-04-2017, 19:04:42
С регенерацией получилось, но команда _UNDO не работает, что не так?
Если твой код оформлен как команда, то _UNDO должно работать.
Название: Re: Удаление графических объектов
Отправлено: Эд от 02-04-2017, 19:11:57
когда дописал забытую мной pEnt->close(), то регенерацию стало не обязательно выполнять. :)
Название: Re: Удаление графических объектов
Отправлено: Александр Ривилис от 02-04-2017, 19:15:26
когда дописал забытую мной p->close(), то регенерацию стало не обязательно выполнять. :)
Без этой строки ты имел все шансы вообще развалить AutoCAD. Именно поэтому я всегда рекомендую использовать интеллектуальные указатели типа
AcDbEntityPointer или AcDbObjectPointer<AcDbимя_класса>, которые автоматически закрывают объект, когда указатель выходит из области видимости и вызывается его деструктор.
Название: Re: Удаление графических объектов
Отправлено: Эд от 02-04-2017, 19:25:11
А что значит развалить Автокад? Может появиться вероятность необходимой переустановки Автокада?
Название: Re: Удаление графических объектов
Отправлено: Александр Ривилис от 02-04-2017, 19:26:37
А что значит развалить Автокад? Может появиться вероятность необходимой переустановки Автокада?
Нет. Есть вероятность появления Fatal Error в данной сессии AutoCAD и потери открытых в нём чертежей.